-4

I want to locate a button which is in an iframe. To do so, I need to use the weird iframe notation:

page.locator('iframe[name="some_iframe_id"]').contentFrame().locator('#some_locator')

On the other hand, locating the same component on a page without an iframe is way simpler:

page.locator('#some_locator')

Why is it not possible to use the usual notation and why do I need to refer which iframe specifically to use? Shouldn't Playwright be able to figure this out on its own?

asked Sep 8 at 13:27
2
  • Simply put - iFrames are hard. There's a more in depth answer that explains how iFrames differ from regular elements (or even frames), but I'm not the one to give that answer. FWIW, this complexity in automated testing isn't a playwright-specific issue -> Selenium and Cypress also have special handling for iFrames as well (selenium.dev/documentation/webdriver/interactions/frames and cypress.io/blog/working-with-iframes-in-cypress), and I'd wager almost every other framework has some consideration as well. Commented Sep 8 at 13:55
  • Do you have a use case where this proposed behavior would help you? Commented Sep 8 at 14:02

1 Answer 1

2

It's a matter of logical separation. iframes are essentially webpages inside of webpages, each with an isolated DOM, JS execution context and security boundaries, so it makes sense to treat each frame as explicitly distinct from Playwright's perspective. This is similar to how one browser has many contexts (windows), which have many pages (tabs), which have many frames. The ability to locate across frames wouldn't make sense or offer practical value relative to the cost, just like locating across pages or contexts doesn't, either.

You could think of your page variable as simply a frame object that happens to be top-level; it has many more functions that can be used on the page/top-level frame than a pure locator, which you can think of as a blueprint for selection and action within a frame.

To be more concrete, if the parent page and iframes all have id="some_locator" elements in them, then it'd be extremely confusing to try to figure out which element is in which frame using your proposed behavior. Given this, unless you have a use case I can't imagine and hasn't been made clear, the proposed behavior doesn't add obvious value to me.

Usually, iframes are nested one level deep, and you can keep a reference to your content frame, similar to how you keep a reference to a page. You only have to incur the syntactical cost once per frame. If you're finding it awkward to work with frames, I suggest sharing that, because there might be a direct solution using Playwright's existing model.

Note that shadow roots are auto-expanded, but this more sense because it's within the same DOM, JS execution context and security boundary, and you don't need to take page-like operations on the shadow root element.

There are likely performance costs to auto-expand iframes that aren't incurred with the shadow DOM.

answered Sep 8 at 14:08
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.