Open Bug 1867810 Opened 7 months ago Updated 28 days ago

Actions performed on elements inside a cross-origin iframe from the parent don't not trigger events

Categories

(Remote Protocol :: WebDriver BiDi, defect, P2)

defect

Tracking

(Not tracked)

People

(Reporter: Sasha, Unassigned)

References

(Blocks 2 open bugs)

Details

(Whiteboard: [webdriver:backlog])

We have now two Puppeteer tests which fail for bidi (https://searchfox.org/mozilla-central/source/remote/test/puppeteer/test/src/oopif.spec.ts#230 and https://searchfox.org/mozilla-central/source/remote/test/puppeteer/test/src/click.spec.ts#440) because they perform click actions on the elements inside cross-origin iframe, and these actions don't trigger event.

The wdspec test to reproduce the issue (same-origin case will pass, cross-origin will fail):

@pytest.mark.parametrize("domain", ["", "alt"], ids=["same_origin", "cross_origin"])
async def test_click_in_iframe(bidi_session, top_context, inline, url, domain):
    iframe_url = inline(
        f"<iframe width='100%' height='500px' src={url('/webdriver/tests/support/html/test_actions.html', domain=domain)}></iframe>"
    )
    await bidi_session.browsing_context.navigate(
        context=top_context["context"],
        url=iframe_url,
        wait="complete",
    )

    all_contexts = await bidi_session.browsing_context.get_tree(
        root=top_context["context"]
    )
    iframe_context = all_contexts[0]["children"][0]

    actions = Actions()
    (
        actions.add_pointer()
        .pointer_move(x=52, y=177)
        .pointer_down(button=0)
        .pointer_up(button=0)
    )

    await bidi_session.input.perform_actions(
        actions=actions, context=top_context["context"]
    )

    events = await get_events(bidi_session, iframe_context["context"])
    assert len(events) == 4

Quick note about https://searchfox.org/mozilla-central/rev/68b1b0041a78abd06f19202558ccc4922e5ba759/remote/test/puppeteer/test/src/click.spec.ts#440

The test seems to send the click via the frame

await frame!.click('button');

But this relies on ElementHandle:click:

  async click(
    this: ElementHandle<Element>,
    options: Readonly<ClickOptions> = {}
  ): Promise<void> {
    await this.scrollIntoViewIfNeeded();
    const {x, y} = await this.clickablePoint(options.offset);
    await this.frame.page().mouse.click(x, y, options);
  }

clickablePoint computes coordinates relative to the topmost frame and this.frame.page() will return the Page owning the Frame, which is implemented using this.mainFrame().click(...). So even if the test looks like it's using the frame, the actual action is dispatched to the topmost context.

As Julian just commented this is happening because the action is performed from the top-level browsing context but not the one from the iframe.

I wonder why the page is used and not directly the iframe.

Summary: Actions performed on the element inside cross-origin iframe don't not trigger events → Actions performed on elements inside a cross-origin iframe from the parent don't not trigger events

I assume that's exactly what the test is trying to check. But indeed there's a workaround that seems easier for almost any reasonable scenario: dispatch the command to the element in the child frame rather than using coordinates in the parent frame. Therefore unless we have strong evidence that this is a common pattern, I don't think we should consider it a blocker.

Given by Alex all events for Chrome need to be send via the top frame in Chrome to allow hit testing and other things. Given that it crosses browsing context boundaries and even processes we indeed cannot support that right now because with EventUtils we dispatch to a specific window only, and it can only bubble down for in-process iframes.

The current option is to allow BFCache in parent for BiDi, but keep the site isolation disabled until bug 1773393 has been fixed.

Severity: -- → S3
Priority: -- → P2
Whiteboard: [webdriver:backlog]
You need to log in before you can comment on or make changes to this bug.