whatwg / dom

DOM Standard
https://dom.spec.whatwg.org/
Other
1.54k stars 286 forks source link

Closed Shadow DOM blocks accessibility testing #1290

Closed tgrushka closed 1 month ago

tgrushka commented 1 month ago

What is the issue with the DOM Standard?

As a user and a developer / accessibility engineer who is legally blind, I ask for your consideration of a major barrier for both users and developers / testers in terms of accessibility that has not been given much voice in the Shadow DOM discussions, but its urgency is increasing.

The problem

I understand Shadow DOM and the usefulness of encapsulation of components. What I do not fully understand is the need to have closed Shadow DOM (specifically, shadowrootmode="closed") and the lack of any mechanism to even see (via JavaScript) the presence of closed declarative shadow roots in the page at all -- or whether that is even a WhatWG / W3C standard, or just a Google / Chrome team decision.

Nonetheless, the shadow root is now ubiquitous (and closed mode even misused by developers thinking it is a security measure), and its usage, particularly declarative with server-side rendering (SSR), is only increasing.

Many developers believe the web is becoming more accessible. However, it is actually becoming less-so, partly due to the complexity of testing with features such as Shadow DOM, iframes, etc. that have been introduced since the 90s. While these features may make life easier for developers, they make end-to-end accessibility testing much more difficult because of all the different and convoluted workarounds, such as:

Some may ask the question: why do accessibility testing tools even need to test "closed" components, since these components should have already been tested by the developer? I argue that the answer is in the question, and further, that e2e tests are equally important to the unit tests of the components.

Proposed solutions

Please, if at all possible, give developers a way to override closed shadow DOM hosts to be open. I noticed this was done for Chrome Extensions. But there should be a way, since it is a DOM standard, to override these for testing. I can hear some developers screaming that they don't want their closed components being messed with; however, this is not sensible from an accessibility standpoint, and the priority should be on the user who needs the accessibility, then on the developer/author who authored the page and wants to make their page accessible, and then finally on the developers of frameworks and components.

I can just envision tons of closed shadow DOM components coming out into web frameworks in the near future, because that's the "easy way out" in terms of making a component work "anywhere," and when has just trusting developers to "do the right thing" without giving users, authors, and testers a way to override these behaviors actually worked?

I argue that:

  1. The author of a page should be able to disable closed shadow DOM on the page, because the author of the page takes priority over the author of a component on that page (especially if that component is part of a UI framework built by a 3rd party). This should not present a merit problem since the standard explicitly states that Shadow DOM is not for security.

    • Making closed shadow roots "read only" might be half-way acceptable, but (accessibility) and other testing often requires components to be manipulated via scripts, but of course human interactions could be simulated as long as the results could be read from the component. This would make these components more difficult to test, but at least possible to test without HTTP request interception.
  2. At minimum, browser automation tools should be able to set a flag, issue a command, etc. to disable closed shadow roots and make the browser treat them as open. But this would be up to each browser vendor, again presenting testers with a huge dependence on each browser to allow such a workaround.

I hope the first option could be both declarative and imperative, again such that request interception would not be required to run tests on a page with closed shadow roots.

My first choice would be removal of closed shadow roots from the standard (if they are even part of the standard), or at least the standard stating that all shadow roots are open. If developers try to understand accessibility better, and the importance of testing, I don't see how this would be so controversial, especially since interfering with a Shadow DOM tree requires a deliberate effort and can't seem to happen accidentally anyway.

My second choice would be overriding the closed state of the shadow root deliberately by 1. above, possibly as a meta tag, body or window property, that could be set both declaratively and imperatively.

My third choice would be to make closed shadow roots "read only", such that JavaScript could not modify properties inside them (aside from user extensions), but again, I'm not foreseeing all the testing challenges this might present (not to mention user CSS, which I use all the time), so hope everyone doesn't jump on this solution first.

Conclusion

In conclusion, the problem is that closed shadow roots are near impossible to test as part of end-to-end (e2e) testing for accessibility:

Thank you for your consideration.

annevk commented 1 month ago

This was an issue for a while, but https://github.com/w3c/webdriver/issues/350 has been resolved and WebDriver is the recommended way to do such automated testing. E.g., https://w3c.github.io/webdriver/#get-element-shadow-root.

If you're interested in reading more about the rationale behind closed shadow roots I wrote up https://annevankesteren.nl/2019/10/encapsulation-theory a while back summarizing some of the discussion on that front.