Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature] CSS.forcePseudoState #3347

Closed
gilles-yvetot opened this issue Aug 7, 2020 · 14 comments
Closed

[Feature] CSS.forcePseudoState #3347

gilles-yvetot opened this issue Aug 7, 2020 · 14 comments

Comments

@gilles-yvetot
Copy link

Hello there,

Thanks for the great work done on pptr and now on pw 👍

I have been trying to force the CSS pseudo state of an element to hover. I want this css state to be "permanent" so I cannot use elementHandle.hover(). I have trying to use a CDP session to do that but it is very hard to find the nodeId needed to call this function. Especially when you work with extension iframes (I could not find a way to identify an element by its XPath).

Thanks a lot

@gilles-yvetot
Copy link
Author

One way I could solve the issue is to have a way to access the CDP client/session of a frame or an elementHandle

@mxschmitt
Copy link
Member

This issue looks pretty similar to #3345

@gilles-yvetot
Copy link
Author

Yeah they look very similar. Sorry I did not see it before posting

@pavelfeldman
Copy link
Member

Could you share more on your use case?

@gilles-yvetot
Copy link
Author

The idea is to let a user select an element in the page but I'd like to keep it "activated". And some elements only stay visible on hover.

@yury-s
Copy link
Member

yury-s commented Nov 13, 2020

@gilles-yvetot do I get it right that you want to "activate" the pseudo element, keep it in that state and and the let the user select it? If so, can you clarify what is the user action that would "select" the pseudo-element?

@gilles-yvetot
Copy link
Author

@yury-s I want to activate the CSS pseudo state, like hover, not the pseudo element, like :before.

But the real question is more to be able to access the CDP client/session of an elementHandle to retrieve the nodeId that I can use with CDP after

@yury-s
Copy link
Member

yury-s commented Nov 14, 2020

You could create CDP session for the page and then evaluate node id using CDP commands, not much help from playwright in that case but it should solve your problem.

@gilles-yvetot
Copy link
Author

@yury-s Yep that's what I ended up doing. But I could not use XPath though. So I converted my XPath to a classic query selector then start forcing hover from the document root to the target element (if that makes sense)

@dgozman
Copy link
Contributor

dgozman commented Nov 23, 2020

@gilles-yvetot Did you manage to find nodeId with your workaround? Overall, this does not seem like a feature that would be useful to a lot of Playwright users, but I'd like to help you with your CDP quest 😄

@gilles-yvetot
Copy link
Author

@dgozman thanks a lot! Yeah I have a working solution:

  • converting the Path to a selector
  • enabling CSS and DOM
  • getting the document
  • forcing the CSS state hover on the root, aka <html> element
  • adding "parts" of the selector to get the child of the root, e.g <body>
  • forcing the CSS state on this child element
  • keep adding "parts" of the selector and forcing the state until the desired node

@dgozman
Copy link
Contributor

dgozman commented Nov 23, 2020

@gilles-yvetot Wonderful! Feel free to ask more questions when the help is needed.

@dgozman dgozman closed this as completed Nov 23, 2020
@codingedgar
Copy link

@dgozman thanks a lot! Yeah I have a working solution:

  • converting the Path to a selector
  • enabling CSS and DOM
  • getting the document
  • forcing the CSS state hover on the root, aka <html> element
  • adding "parts" of the selector to get the child of the root, e.g <body>
  • forcing the CSS state on this child element
  • keep adding "parts" of the selector and forcing the state until the desired node

How did you do it? could you share a snippet?

@jonathantneal
Copy link

For posterity, I had to do something similar, and this is what it looked like in code.

Converting the Path to a selector:
Here is a gist of the logic I used to get the NodeID of an Element, which in my case needed to cross iframe boundaries.

Enabling CSS and DOM:

await cdp().send("DOM.enable")
await cdp().send("CSS.enable")

From here, I skip to forcing the pseudo class. I did not need to get the document, as I did not desire toggling &:hover down the entire tree. This is how I forced the hover pseudo class.

const nodeId = await getNodeId(element)

await cdp().send("CSS.forcePseudoState", { nodeId, forcedPseudoClasses: ["hover"] })

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants