Lets say I have a class containing page objects. If I instantiate that class in a test, then I can use the page objects as you normally would with playwright. I would like to get the css value as a string from one of those page objects so I can use it in a custom function.
This should give you an idea of what I mean
export class PageObjects{
constructor(page){
this.obj1 = page.locator('#table tbody tr')
}
}
test('Get Values and header names from a table', async({page})=> {
// Page objects
const pageObjects = new PageObjects(page)
// I want the css from the page object?? in other words
// how do I pull out the '#table tbody tr' css value as a string?
// in other words I want cssString value to be #table tbody tr
// I have tried _selector but it just returns an empty string
cssString = pageObjects.obj1.??????
})
is there a way to get the css value out of a locator?
3
Answers
The answer is that you cannot get the string argument passed to the locator in Playwright. But the point was really to use the css selector string to manipulate the DOM. So if you need to manipulate the HTML elements inside some specific element then you can first set up a page object class and define that element as a Locator. Then you can import the class into your test and instantiate the class. Then you can call the locator as a property on the class. Once you have done this then you can use myLocator.evaluate( el=>{}) to access and manipulate the DOM.
In general ,this is not recommended approach for maintaining locators.
Use Page Object Model which is a software design pattern for better code abstraction, reusability and long term maintenance.
In Page Object Model, all the application functionality is captured as black boxes in the form of page object methods which also encapsulate UI objects(CSS/Xpath) as well so that they can be added or updated from a single place of reference- DRY principle.
Full Code Example:
Page Object:
Test:
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:I’ve taken the liberty to rename a couple of variables: plural usually refers to collections like arrays and objects, so
PageObjects
would be typedPageObject[]
, andobj1
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
: