I am currently working with a protractor list page object. By default, this object returns instances of ElementFinder
, but there is a way to customize it to return instances of ComplexType
like the following:
class ComplexType {
foo = 'foo';
constructor(public element: ElementFinder) {}
}
const list = new List<ComplexType>({ element: ..., type: ComplexType});
expect(list.get(0).foo).toBe('foo');
Below is the definition of the page object:
import { ElementFinder } from 'protractor';
export interface ListItem<T> {
new(element: ElementFinder): T;
}
export interface ListOptions<T> {
element: ElementFinder;
selector?: string;
type?: ListItem<T>;
}
export class List<T = ElementFinder> {
public readonly element: ElementFinder;
private selector: string;
private type: (element: ElementFinder) => T;
get items() {
return this.element.$$(this.selector);
}
get length() {
return this.items.count();
}
constructor(options: ListOptions<T> | ElementFinder, selector?: string) {
if (options instanceof ElementFinder) {
this.element = options;
this.selector = selector || 'li';
this.type = (element: ElementFinder) => element;
} else {
this.element = options.element;
this.selector = options.selector || 'li';
this.type = (element: ElementFinder) => new options.type(element);
}
}
get(index: number): T {
return this.type(this.items.get(index));
}
}
The issue I am facing is that TypeScript is unable to recognize that T can sometimes be an ElementFinder. Therefore, when I return an instance of ElementFinder, it raises an error indicating that the element finder does not match T.
This has left me confused. Is there a solution to this problem?