I'm not sure I follow the motivation for this pattern (Playwright already has a Page
abstraction--why do you want to wrap it with another--unless you're going for a POM as described in this answer?) and it smells like a potential xy problem, but I don't see why you can't set that argument as a varible on your instance:
export class PageObject {
constructor(page) {
this.selector = '#table tbody tr';
this.locator = page.locator(this.selector);
}
}
// ...
const pageObject = new PageObject();
console.log(pageObject.selector);
I've taken the liberty to rename a couple of variables: plural usually refers to collections like arrays and objects, so PageObjects
would be typed PageObject[]
, and obj1
is an unclear name.
It's a bit strange to hardcode that selector. This effectively makes the class single purpose only, so you might consider making that a parameter, depending on your use case.
Even if you are able to find a property on Playwright locators holding the argument, I wouldn't rely on it, since there is no documented public property in the API.
If you want the argument in one place, it's easy enough to hardcode it as part of a global selector config, or bind it in a wrapper function if some aspects of the selector may change.
I suggest taking a step back and re-approaching your design from the top down. Start from your goals and inquire whether this really the right abstraction for achieving them. Often, if things seem hard to do and you find you're battling your design or the language, it's probably not the right approach.
Generally, the best approach is to not write abstractions immediately. Then, once the cut points emerge, you can write accurate, non-premature and robust abstractions that solve clear problems.
If I misunderstood the question and you want to get the CSS style of the elements, you can use getComputedStyle
:
const style = await page
.locator("#table tbody tr")
.evaluateAll(els =>
els.map(e =>
Object.fromEntries(
[...getComputedStyle(e)].map(k => [
k,
getComputedStyle(e)[k],
])
)
)
);