SeleniumHQ / selenium

A browser automation framework and ecosystem.
https://selenium.dev
Apache License 2.0
30.48k stars 8.15k forks source link

[🐛 Bug]: Safari nested iFrame 500 error #10039

Closed mwilc0x closed 2 years ago

mwilc0x commented 2 years ago

What happened?

Hi Selenium team,

I'm having difficulty testing a piece of code that uses Selenium and SafariDriver through the NightwatchJS library. The code is working fine for Chrome and FF. I'm not 100% sure if it's a problem with nightwatch or something deeper, so am reaching out here. If this is not correct place, or somewhere better can ask, please let me know!

So far I have tried:

After debugging more am starting to think this could be an issue with either Selenium or SafariDriver. Or perhaps some misunderstanding or misconfiguration on my part.

Environment

safaridriver - Included with Safari 14.1.1 (16611.2.7.1.4)
"selenium-server": "3.141.59",
"selenium-webdriver": "4.0.0",

What is the problem test?

The test needs to access an iframe within an iframe from top level document. The setup looks something like this:

HTML

<body>
  <iframe id="top-iframe" src="about:blank">
    #document
      <html>
        <body>
          <container>
            <!-- access this iframe to test -->
            <iframe id="nested-iframe" src="news.google.com"></iframe>
          </container>
        </body>
      </html>
  </iframe>
</body>

Where #nested-frame will need to be accessed from the top level document for inspection of content.

The test code is using NightwatchJS, more details about config, setup and code are in the GitHub issue.

Problem Summary

The problem is that to access the nested iFrame, it needs to first find #top-frame web element, use the returned web element and pass it to frame which makes the WebDriver call to change context of test session to that frame. This is all good with Chrome, FF, and Safari as they can all find this frame web element and make the switch into the frame context. My test for Safari was switching into first iFrame context. And now here is where I think there is maybe a bug or I am not understanding something:

After switching into first frame in Safari, I do an element lookup for a regular tag <container></container> which is returned as a web element. I then try a couple different things using the web element ID:

<container>
  <iframe src="news.google.com"></iframe>
</container>

→ Running command: elementIdElements ('node-3AC0121F-9C54-4BC5-B548-532E7E615BDE', 'tag name', 'span', [Function]) Request POST /session/DD2A827C-5D8E-4C0F-A783-1991E528B25A/element/node-3AC0121F-9C54-4BC5-B548-532E7E615BDE/elements { using: 'tag name', value: 'span' } Response 200 POST /session/DD2A827C-5D8E-4C0F-A783-1991E528B25A/element/node-3AC0121F-9C54-4BC5-B548-532E7E615BDE/elements (37ms) { value: [] }

→ Running command: elementIdElements ('node-700E05B9-1C42-4289-A06F-B4BF9A8A0867', 'tag name', 'iframe', [Function]) Request POST /session/0A778850-DDC6-42EE-9F8C-60A0998962D2/element/node-700E05B9-1C42-4289-A06F-B4BF9A8A0867/elements { using: 'tag name', value: 'iframe' } Response 500 POST /session/0A778850-DDC6-42EE-9F8C-60A0998962D2/element/node-700E05B9-1C42-4289-A06F-B4BF9A8A0867/elements (27ms) { value: { error: 'unknown error', message: '', stacktrace: '' } } Error while running .locateMultipleElementsByElementId() protocol action: An unknown server-side error occurred while processing the command.

It is very puzzling, my latest thinking was maybe it was a cross origin issue. But then I read on WebDriver switch to frame:

NOTE WebDriver is not bound by the same origin policy, so it is always possible to switch into child browsing contexts, even if they are different origin to the current browsing context.

And I also tried checking Disable Cross Origin Restrictions from Safari Developer menu.

I'm not sure how to further debug. Maybe someone else with a fresh perspective could have a suggestion or if someone has run into a similar situation as this. Has anyone run into a similar issue like this? TIA!

How can we reproduce the issue?

The code is written with NightwatchJS.
I have an open issue on their repo [here](https://github.com/nightwatchjs/nightwatch/issues/2943) that has more info.

Here is some pseudo code:

<body>
  <iframe id="top-iframe" src="about:blank">
    #document
      <html>
        <body>
          <container>
            <!-- access this iframe to test -->
            <iframe id="nested-iframe" src="news.google.com"></iframe>
          </container>
        </body>
      </html>
  </iframe>
</body>

```js
let webIdA = findElement('#top-iframe');
await frame(webID); // switch into first frame

let webIdB = findElement('container'); // find container web ID in first frame

// returns web element for container
// now try to find the iframe underneath this web element using the ID just returned
let frameId = findElementsById(webIdB, 'iframe')

// return 500 server error Safari

### Relevant log output

```shell
I look for an element that I know does not exist underneath.

`
→ Running command: elementIdElements ('node-3AC0121F-9C54-4BC5-B548-532E7E615BDE', 'tag name', 'span', [Function]) Request POST /session/DD2A827C-5D8E-4C0F-A783-1991E528B25A/element/node-3AC0121F-9C54-4BC5-B548-532E7E615BDE/elements { using: 'tag name', value: 'span' } Response 200 POST /session/DD2A827C-5D8E-4C0F-A783-1991E528B25A/element/node-3AC0121F-9C54-4BC5-B548-532E7E615BDE/elements (37ms) { value: [] }
`

I look for the iframe I know is there.

`
→ Running command: elementIdElements ('node-700E05B9-1C42-4289-A06F-B4BF9A8A0867', 'tag name', 'iframe', [Function]) Request POST /session/0A778850-DDC6-42EE-9F8C-60A0998962D2/element/node-700E05B9-1C42-4289-A06F-B4BF9A8A0867/elements { using: 'tag name', value: 'iframe' } Response 500 POST /session/0A778850-DDC6-42EE-9F8C-60A0998962D2/element/node-700E05B9-1C42-4289-A06F-B4BF9A8A0867/elements (27ms) { value: { error: 'unknown error', message: '', stacktrace: '' } } Error while running .locateMultipleElementsByElementId() protocol action: An unknown server-side error occurred while processing the command.
`

Operating System

macOS Big Sur

Selenium version

4.0.0

What are the browser(s) and version(s) where you see this issue?

Safari

What are the browser driver(s) and version(s) where you see this issue?

safaridriver - Included with Safari 14.1.1 (16611.2.7.1.4)

Are you using Selenium Grid?

i don't think so

github-actions[bot] commented 2 years ago

@michaelwilcox, thank you for creating this issue. We will troubleshoot it as soon as we can.


Info for maintainers

Triage this issue by using labels.

If information is missing, add a helpful comment and then I-issue-template label.

If the issue is a question, add the I-question label.

If the issue is valid but there is no time to troubleshoot it, consider adding the help wanted label.

After troubleshooting the issue, please add the R-awaiting answer label.

Thank you!

titusfortner commented 2 years ago

I don't understand why you need to locate container. findElement should work for any nested element.

I don't know JS or Nightwatch, but you should be able to do something like:

let topFrame = findElement('#top-iframe');
await frame(topFrame); // switch into first frame
let nestedFrame = findElement('#nested-iframe');
await frame(nestedFrame); // switch into nested frame

I know this works on Safari because the Watir tests verify this functionality and they are passing.

mwilc0x commented 2 years ago

Hi,

Thank you for your response.

I have setup a minimal test repro here that is using the hosted demo site am testing on.

Apologies for the container lookup code, that was after had tried a few other lookup methods including just finding the iframe after switching into first frame.

What do you think about the first frame having src="about:blank" as URL? Could Safari have issues with content that is dynamically loaded, if nested iframe loaded after page load?

titusfortner commented 2 years ago

Ok, I can reproduce the error with your use case.

Calling this within the top_iframe:

irb(main):052:0> nested_iframe = driver.find_elements(tag_name: 'iframe')

results in this:

2021-11-15 11:30:58 INFO Selenium <- {"value":{"error":"unknown error","message":"","stacktrace":""}}

Unfortunately this is a Safari bug, since Selenium is sending the correct information to the driver and the driver isn't doing the correct thing.

You can file a bug with Apple here: https://feedbackassistant.apple.com/

mwilc0x commented 2 years ago

Thank you for the confirmation!

mwilc0x commented 2 years ago

Have filed https://feedbackassistant.apple.com/feedback/9761142 for this.

github-actions[bot] commented 2 years ago

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.