Skip to content

Playwright 4.x bug: switchTo doesn't handle nested frames properly #5688

Description

@nikzupancic

After upgrading to v4 the switchTo behavior seems incorrect or at least inconsistent when working with nested iframes. The switch to iframe located on the top level works correctly and the context seems to be set properly.
I can verify and interact with elements within the first iframe. switchTo(nestedIframe) step passes but after that it seems to get into a state where nothing is visible to the driver any more. The elements present in nested iframe are never detected, neither are those within the first frame or on top-level outside of any frames.

Tested with codeceptjs@4.1.0 and playwright-core@1.61.1. Reproduction script:

Scenario('iframe test', ({ I }) => {
    I.amOnPage('https://www.dezlearn.com/nested-iframes-example/')

    I.waitForElement('#parent_iframe', 10)
    I.switchTo('#parent_iframe')

    I.waitForElement('#u_5_5')

    I.waitForElement('#iframe1')
    I.switchTo('#iframe1')

    I.waitForElement('#u_5_6') // fails on v4
    
    // below 2 calls are expected to fail with expected switchTo behavior but are included just to show that context seems broken 
    // I.waitForElement('#u_5_5') // located in parent iframe 
    // I.waitForElement('#parent_iframe') // located on top level
})

On the other hand doing the same thing using within seems to work but that has its own downsides so I'm not keen on relying solely on that.

Scenario('iframe test', ({ I }) => {
    I.amOnPage('https://www.dezlearn.com/nested-iframes-example/')

    I.waitForElement('#parent_iframe', 10)
    within({ frame: ['#parent_iframe', '#iframe1'] }, () => {
        I.waitForElement('#u_5_6')
    })
})

This seems to be regression as it works fine on 3.7.9

Activity

  1. neskoncno commented on Aug 18, 2026

    @neskoncno

    Minimal repro to comfirm this is Playwright specific regression: a local static fixture with a 3-level nested iframe (top → #outer → #inner → target element), tested on codeceptjs@4.1.0.

    Same result: switchTo('#outer') then switchTo('#inner') both report passed, but the following assertion on the target element times out — context silently ends up wrong.

    Ran the identical scenario through the other helpers against the same fixture:

    Helper Result
    Playwright ❌ fails
    Puppeteer ✅ works
    WebDriver ✅ works

    So this looks Playwright specific, not a general switchTo() regression. Your within({ frame: [...] }) workaround also checks out on Playwright.

    Repro + configs for all three helpers: https://github.com/neskoncno/cjs4-iframe-playwright-bug

    Source of introduced regression cb7efd6#diff-5dc6e0a9028f00d161e530bc3b734e92d0497c131429e67b07e87a9224e4ecda

  2. added a commit that references this issue on Sep 13, 2026
    54dd76d
  3. added a commit that references this issue on Sep 30, 2026
    bc7102d
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions