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鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature]: expose Frame Ids #30261

Closed
himat opened this issue Apr 5, 2024 · 7 comments
Closed

[Feature]: expose Frame Ids #30261

himat opened this issue Apr 5, 2024 · 7 comments

Comments

@himat
Copy link

himat commented Apr 5, 2024

馃殌 Feature Request

Why does playwright not expose a unique frame ID on the Frame object?

There is a unique ID for every Frame that is exposed in the CDP

So why does Playwright not expose this?
I need a way to distinguish frames and track them across time, so using just the .name() property is not sufficient since two frames could have the same name, and the names can change over time.

Puppeteer at least has an internal variable _id that you can use there too (source)

Electron also exposes the frame ID

Example

No response

Motivation

Impossible to uniquely identify frames right now

@dgozman
Copy link
Contributor

dgozman commented Apr 5, 2024

@himat ID is an internal implementation detail. You can always create a Map<Frame, number> or use a symbol and lazily auto-generate ID for each frame.

const idMap = new Map<Frame, number>();
function getFrameId(frame: Frame) {
  if (!idMap.has(frame))
    idMap.set(frame, idMap.size + 1);
  return idMap.get(frame)!;
}

@himat
Copy link
Author

himat commented Apr 5, 2024

@dgozman But that relies on only having one instance of a given Frame to make sure the reference comparison works right?
i.e. If I get a Frame at one point and store it in variable f1 and a Frame again later and store it in f2 (and say these came from two separate calls to page.frames()), then I want to ensure that if they're the same underlying frame that f1 === f2 should equal true.
And even if a Frame changes over time, does Playwright itself manage the frame internally to make sure that it always only has one reference to each Frame?

@himat
Copy link
Author

himat commented Apr 5, 2024

I also noticed that playwright has an internal only guid field. Is that also stable, or are the guid assigned to each instance and therefore wouldn't work? In other words, are these guids, a unique UI on the reference or on the actual underlying value?

@dgozman
Copy link
Contributor

dgozman commented Apr 5, 2024

@himat Frame object is always the same for the same frame. guid is a part of the Frame object, but since it's an internal implementation detail, it might disappear at any moment as well.

@himat
Copy link
Author

himat commented Apr 5, 2024

@dgozman, ok so using Frame makes sense for that

But I have another usecase, where I need to reach into the CDP to listen for events since playwright does not expose these

  const cdpClient = await page.context().newCDPSession(page)
  await cdpClient.send("DOM.enable")
  await cdpClient.send("Network.enable")

  cdpClient.on("Network.requestWillBeSent", onNavigationStart)
  function onNavigationStart(params: Protocol.Network.RequestWillBeSentEvent) {
    const frames = page.frames()
    const navigationFrameId = params.frameId
    const isMainFrame = frames.find((frame) => frame.<ID??> === navigationFrameId) !== -1
    if (!isMainFrame) return
    ...
}

As you can see, I want to detect the navigation start for a page, and the RequestWillBeSentEvent gives me back a frameId, and I want to only run this algorithm on the main frame, but I can't do that here since you don't expose the frame ID.
Also, just wanted to check, but the frame object guid is entirely different from the actual Frame's ID right? Was wondering if I could even use the guid here even if temporarily even though its internal

@dgozman
Copy link
Contributor

dgozman commented Apr 5, 2024

@himat Interoperating with CDP is not a goal for Playwright. The use of CDP is an implementation detail. If you'd like to work with CDP directly, feel free to retrieve the frame tree over CDP and call any protocol methods you'd like. Note that Playwright does not guarantee that it won't break after you call some CDP methods, so use it at your own risk.

Also, just wanted to check, but the frame object guid is entirely different from the actual Frame's ID right?

Yes, guid is a separate randomly generated id.

@dgozman
Copy link
Contributor

dgozman commented Apr 8, 2024

Closing as per above. If you encounter more problems, please file a new issue by filling in the "Bug Report" template.

@dgozman dgozman closed this as completed Apr 8, 2024
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

2 participants