Manuals / Playwright with Python / Ch 15

Part 2 · Core InteractionsIntermediate40 min read

9. Tabs, Windows, iFrames

Playwright with Python · 244 pages source format

with page.context.expect_page() as new_page_info: page.get_by_role("link", name="Open in new tab").click() new_page = new_page_info.value new_page.wait_for_load_state() print(new_page.title()) The with ... expect_page() pattern registers the listener for the new page event before the click happens, avoiding a race condition where the new tab opens before you started listening for it.

What you'll learn

  • with page.context.expect_page() as new_page_info: page.get_by_role("link", name=
  • expect_page() pattern registers the listener for the new page event before the c
  • page.context.

Overview

new_page = new_page_info.value

The with ... expect_page() pattern registers the listener for the new page event before the click happens, avoiding a race condition where the new tab opens before you started listening for it.

Run / study this snippet
with page.context.expect_page() as new_page_info:
Interactive study board
OverviewDrag stickies · tap for tips
Study mapDrag stickies · tap for tipsKeep it shortdrag · tap →Name the waitdrag · tap →Scope locatorsdrag · tap →Trace when stuckdrag · tap →One browser firstdrag · tap →Isolate statedrag · tap →Assert the UIdrag · tap →Retry wiselydrag · tap →Seed datadrag · tap →Close the loopdrag · tap →Keep it shortdrag · tap →Name the waitdrag · tap →Scope locatorsdrag · tap →Trace when stuckdrag · tap →One browser firstdrag · tap →Isolate statedrag · tap →Pathwise hackdrag · tap →Page under testdrag · tap →Multi-browserdrag · tap →Automation pathdrag · tap →Tooling nodedrag · tap →
Clear?

page.context.expect_page()

What it does: Context manager that captures a reference to a newly opened tab/page.

Types/params:

Pointers: Must wrap the action that triggers the new tab — registering after the click risks missing the event.

Once you have references to multiple pages, you simply call actions on whichever page object represents the tab you want — there's no "switch to window" concept like Selenium's

times.

  • Used as a context manager: with page.context.expect_page() as info:
  • info.value (accessed after the block) → the new Page object
Run / study this snippet
original_page.bring_to_front()   # optional — brings a page to the foreground visually
Interactive study board
page.context.expect_page()Drag stickies · tap for tips
Study mapDrag stickies · tap for tipsKeep it shortdrag · tap →Name the waitdrag · tap →Scope locatorsdrag · tap →Trace when stuckdrag · tap →One browser firstdrag · tap →Isolate statedrag · tap →Assert the UIdrag · tap →Retry wiselydrag · tap →Seed datadrag · tap →Close the loopdrag · tap →Keep it shortdrag · tap →Name the waitdrag · tap →Scope locatorsdrag · tap →Trace when stuckdrag · tap →One browser firstdrag · tap →Isolate statedrag · tap →Pathwise hackdrag · tap →Page under testdrag · tap →Multi-browserdrag · tap →Automation pathdrag · tap →Tooling nodedrag · tap →
Clear?

page.bring_to_front()

What it does: Brings a specific page/tab to the visual foreground.

Types/params: No parameters.

Pointers: Mostly cosmetic for headed debugging — not required to interact with a background tab programmatically.

frame = page.frame_locator("#payment-iframe")

Common real-world case: third-party payment widgets (Stripe, PayPal) are almost always embedded via iframe for security/PCI-compliance reasons.

Run / study this snippet
frame.get_by_label("Card number").fill("4242 4242 4242 4242")
Interactive study board
page.bring_to_front()Drag stickies · tap for tips
Study mapDrag stickies · tap for tipsKeep it shortdrag · tap →Name the waitdrag · tap →Scope locatorsdrag · tap →Trace when stuckdrag · tap →One browser firstdrag · tap →Isolate statedrag · tap →Assert the UIdrag · tap →Retry wiselydrag · tap →Seed datadrag · tap →Close the loopdrag · tap →Keep it shortdrag · tap →Name the waitdrag · tap →Scope locatorsdrag · tap →Trace when stuckdrag · tap →One browser firstdrag · tap →Isolate statedrag · tap →Pathwise hackdrag · tap →Page under testdrag · tap →Multi-browserdrag · tap →Automation pathdrag · tap →Tooling nodedrag · tap →
Clear?

page.frame_locator(selector)

What it does: Returns a locator scoped inside a specific iframe.

Types/params:

contents)

Pointers: Required any time content lives inside an <iframe>. Chain for nested iframes: .frame_locator("#outer").frame_locator("#inner").

Interactive study board
page.frame_locator(selector)Drag stickies · tap for tips
Study mapDrag stickies · tap for tipsKeep it shortdrag · tap →Name the waitdrag · tap →Scope locatorsdrag · tap →Trace when stuckdrag · tap →One browser firstdrag · tap →Isolate statedrag · tap →Assert the UIdrag · tap →Retry wiselydrag · tap →Seed datadrag · tap →Close the loopdrag · tap →Keep it shortdrag · tap →Name the waitdrag · tap →Scope locatorsdrag · tap →Trace when stuckdrag · tap →One browser firstdrag · tap →Isolate statedrag · tap →Pathwise hackdrag · tap →Page under testdrag · tap →Multi-browserdrag · tap →Automation pathdrag · tap →Tooling nodedrag · tap →
Clear?

Checklist