Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[🐛 Bug]: Displayed property of WebElement outputs incorrectly when using ShadowRoot #13623

Open
SitrucHtims opened this issue Feb 23, 2024 · 8 comments
Labels
D-atoms help wanted Issues looking for contributions I-defect

Comments

@SitrucHtims
Copy link

SitrucHtims commented Feb 23, 2024

What happened?

When evaluating the Displayed property of the WebElement. Displayed returns False, but should return True as the element is displayed.

To use the below PowerShell code sample, save the script to a directory that also contains the WebDriver.dll and desired browserdriver.exe

---PowerShell code sample did not display correctly, so I attached as .txt file (Also included in the "How can we reproduce the issue" section---
Example.txt

Execution of the Example outputs:
image

Notice Displayed is False; yet on the page, the element is definitely displayed.
image

I have investigated and the issue seems to come from the use of ShadowRoot on the page and is-Displayed.js not able to correctly evaluate it.

The input element that we are checking the Displayed property on hosts a shadow-root
image

When is-displayed.js evaluates the element, it begins evaluating each element up the tree to the root element. If it were the normal DOM, it would reach the #document element and see this is nodeType 9 and return true if all elements are visible up the tree. In this case, when is-displayed.js begins going up the tree it reaches the "dnx-testfield" which is seen as the shadowRoot. In the case of this page, there is no assignedSlot for the shadowRoot, so null is returned and since null is returned, False is returned for displayed.

This can be seen in the below code; however, I only have the minified .js to work with, so it's a little hard to read.
 function c(d) {
  if (W(d) && "none" == Y(d, "display"))
  return !1;
  var e;
  if ((e = d.parentNode) && e.shadowRoot && void 0 !== d.assignedSlot)
  e = d.assignedSlot ? d.assignedSlot.parentNode : null;
  else if (d.getDestinationInsertionPoints) {
  var f = d.getDestinationInsertionPoints();
  0 < f.length && (e = f[f.length - 1])
  }
  if (Fc && e instanceof ShadowRoot) {
  if (e.host.shadowRoot !== e)
  return !1;
  e = e.host
  }
  return !e || 9 != e.nodeType && 11 != e.nodeType ? e && W(e, "DETAILS") && !e.open && !W(d, "SUMMARY") ? !1 : !!e && c(e) : !0
 }

In the page when a parent element with a populated shadowRoot property is reached, it goes in the this block of code:
  if ((e = d.parentNode) && e.shadowRoot && void 0 !== d.assignedSlot)
  e = d.assignedSlot ? d.assignedSlot.parentNode : null;

In the page, the parent element with shadowRoot is dnx.textfield with label "Email"
image

When this is reached e is set to null because d.assignedSlot (the assignedSlot property value of the current element) is null

Then since e is null and e (the parent element is not type 9 or 11), then it does not return True as it should since the shadowRoot has been reached.
  return !e || 9 != e.nodeType && 11 != e.nodeType ? e && W(e, "DETAILS") && !e.open && !W(d, "SUMMARY") ? !1 : !!e && c(e) : !0

It may not be the right solution, but I was able to address this by adding a conditional to the return that if the parent element matched the parent elements shadowroot property, then return the parent element instead of null when there is no assignedSlot.
  if ((e = d.parentNode) && e.shadowRoot && void 0 !== d.assignedSlot)
  e = d.assignedSlot ? d.assignedSlot.parentNode : d.parentNode == d.parentNode.shadowRoot ? d.parentNode : null;
  else if (d.getDestinationInsertionPoints) {
  var f = d.getDestinationInsertionPoints();
  0 < f.length && (e = f[f.length - 1])
  }

How can we reproduce the issue?

Function Get-Browser {
    Param (
           [Parameter(Mandatory=$true)]
           [ValidateSet("Edge","Chrome")]
           [string]$type
          )
    
    Set-EnvironmentPath

    Add-Type -Path "$($PSScriptRoot)\WebDriver.dll"

    Switch ($type) {
          "edge" {
                  $Driver = New-Object OpenQA.Selenium.Edge.EdgeDriver
                 }
        "chrome" {
                  $Driver = New-Object OpenQA.Selenium.Chrome.ChromeDriver
                 }
    }
    $Driver
}

Relevant log output

Unfortunately I was unable to find a good example of enabling logging with PowerShell, and the logging namespace did not show under OpenQA.Selenium.Internal, so I was not able to include this.

Operating System

Windows 10

Selenium version

PowerShell 5.1.19041.1682

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

Chrome 121.0.6167.185 and Edge 121.0.2277.128 (both 64-bit)

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

ChromeDriver 120.0.6099.109 (3419140ab665596f21b385ce136419fde0924272-refs/branch-heads/6099@{#1483}) Microsoft Edge WebDriver 120.0.2210.121 (6086ec26a02a23b6723b794ef7b81d37e71506e3)

Are you using Selenium Grid?

No

Copy link

@SitrucHtims, 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.

If the issue requires changes or fixes from an external project (e.g., ChromeDriver, GeckoDriver, MSEdgeDriver, W3C), add the applicable G-* label, and it will provide the correct link and auto-close the issue.

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

Thank you!

@SitrucHtims
Copy link
Author

Sorry looks like the PowerShell script in the "How can we reproduce the issue?" section is cut off, but the full script is attached as a .txt file in the "What happened?" section

@diemol
Copy link
Member

diemol commented Feb 27, 2024

Does this happen in Firefox, Safari, and Edge as well?

@SitrucHtims
Copy link
Author

SitrucHtims commented Feb 27, 2024

I know it happens with Chrome and Edge, I can check for FF, but don't have a system to check Safari.

@diemol
Copy link
Member

diemol commented Feb 27, 2024

Can you check? This would hint if it is a ChromeDriver issue or a WebDriver issue.

@SitrucHtims
Copy link
Author

I can confirm the behavior happens for Chrome, Edge, and FireFox. I am unsure about Safari as I do not have a system to test with.

@diemol diemol added the D-atoms label Feb 27, 2024
@SitrucHtims
Copy link
Author

It could actually be that the flow is never intended to reach this line of execution and getting there unintentionally.

if ((e = d.parentNode) && e.shadowRoot && void 0 !== d.assignedSlot)
e = d.assignedSlot ? d.assignedSlot.parentNode : null;
else if (d.getDestinationInsertionPoints) {
var f = d.getDestinationInsertionPoints();
0 < f.length && (e = f[f.length - 1])
}

void 0 !== d.assignedSlot appears to be checking to see if d.assignedSlot has a value or not, but it's using !== which also checks the data type, and null is not equal to undefined from a data type perspective.

IE:
undefined !== null
true
undefined != null
false

Since d.assignedSlot is null, maybe it is intended to skip this and the solution would simply be to change the condition:
from:
void 0 !== d.assignedSlot
to:
void 0 != d.assignedSlot

@titusfortner titusfortner added help wanted Issues looking for contributions and removed R-awaiting answer labels Mar 8, 2024
Copy link

github-actions bot commented Mar 8, 2024

This issue is looking for contributors.

Please comment below or reach out to us through our IRC/Slack/Matrix channels if you are interested.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
D-atoms help wanted Issues looking for contributions I-defect
Projects
None yet
Development

No branches or pull requests

3 participants