microsoft / playwright

Playwright is a framework for Web Testing and Automation. It allows testing Chromium, Firefox and WebKit with a single API.
https://playwright.dev
Apache License 2.0
65.39k stars 3.55k forks source link

[BUG] Unable to access iframe in firefox (works with chromium and webkit) #28082

Open Rafiot opened 10 months ago

Rafiot commented 10 months ago

System info

Source code

Test file (self-contained)

The code isn't fancy, but at least, it's reproducible: cf_locator.click(force=True, timeout=5000) always times out with firefox but works with chromium and webkit.

Important warning: if you manage to load https://nowsecure.nl/ after the cloudflare thing, you land on a blinking page that is very unpleasant. Like really, really unpleasant.

#!/usr/bin/env python3

import random

from playwright.sync_api import Playwright, sync_playwright

def run(playwright: Playwright) -> None:
    # browser = playwright.chromium.launch(headless=False)
    # browser = playwright.webkit.launch(headless=False)
    browser = playwright.firefox.launch(headless=False)
    context = browser.new_context()
    page = context.new_page()
    page.goto("https://nowsecure.nl/")
    page.wait_for_timeout(10000)
    max_tries = 5
    while max_tries > 0:
        while True:
            try:
                cf_locator = page.frame_locator("iframe[title=\"Widget containing a Cloudflare security challenge\"]").get_by_role("checkbox")
                cf_locator.click(force=True, timeout=5000)
                print('click worked')
                break
            except Exception as e:
                print(e)
                page.wait_for_timeout(2000)
        page.wait_for_timeout(2000)
        spinner = page.locator('#challenge-spinner')
        while True:
            if spinner.is_visible():
                print('got a spinner')
                page.wait_for_timeout(2000)
            else:
                print('no spinner')
                break
        max_tries -= 1
        page.wait_for_timeout(2000)

    print('done')
    # ---------------------
    context.close()
    browser.close()

with sync_playwright() as playwright:
    run(playwright)

Steps

Expected

Click works

Actual

Click times out

dgozman commented 8 months ago

Investigation notes. Inside Juggler, Frame.domWindow() returns null, Frame.docShell() returns null and we cannot evaluate inside, and accessing frameElement.contentWindow.docShell during Page.describeNode throws Permission denied to access a property on cross-origin window.

adrianodennanni commented 1 month ago

Just to add to this issue: even if you click on a coordinate on the iframe region, the click is not propagated to inside the iframe. It's like it doesn't exist for Playwright, although it is fully rendered.