I want to create a class that wraps the Playwright’s Locator to add some utility functions.
The behavior of the locator should be exactly the same as the one provided by the testing framework, aside from the added utility functions.
However, if I implement the interface I have to re-implement all the functions manually, which is something I don’t want since the behavior doesn’t change. What is the proper way to do it?
Here some pseudo-code of what I want to do:
// I know I can't extend locator since its an interface but I'm using
// extends to better deliver the concept of what I want to do
export class LocatorWrapper extends Locator {
constructor (...args: any[]) {
super(args);
}
public hoverAndDoubleClick = async () => {
// This function is just a dummy
await this.hover();
await this.click();
await this.click();
}
}
2
Answers
To obtain an extended version of the locator I created a wrapper interface and then only used the locator inside my Page Object Model.
To make the creation of the POM even smoother a fixture can be used. I leave the link to the docs:
How about to look into direction of using
PageObject
model and inheritance?You have base class which has abstract property
mainSelector
that is root. (It can bestring
orLocator
as you prefer, or even you can create constructor for it)and then each your new
PageObject
class would just extend from it.so
TestComponent
could use all methods fromPageObjects
.If you have contexts, you can adjust
PageObject
class to be context independent.This approach can help to easily wrap actions from Playwright and manipulate tab contexts by demand.
Example of this approach on Puppeteer