webcomponents / polyfills

Web Components Polyfills
BSD 3-Clause "New" or "Revised" License
1.14k stars 165 forks source link

[scoped-custom-element-registry]: Support for JSDOM (Jest) #459

Open riovir opened 3 years ago

riovir commented 3 years ago

Description

Please consider altering the polyfill to keep JSDOM's global customElements registry intact. This particular instance also includes some _internal bookkeeping the headless browser uses. Swapping it out completely breaks JSDOM down.

However by swapping it out with a Proxy-ed object that delegates to the polyfill's instance where it can, and allows fallthrough to the original instance seems to also add support to JSDOM.

Motivation

So why consider a "not a real browser" as some would put it? Currently, a large percentage of applications written with traditional frameworks (React or Vue) use Jest including JSDOM (v16+). Currently, web components are often sold to management as a future-proofing investment. Now if we take an organization adopting, say Lion Web Components, suddenly all their Jest user teams' tests start breaking after @open-wc/scoped-elements has updated to use this polyfill.

Note

As far as I managed to test it, the following change to the polyfill would solve the problem for JSDOM. I'm happy to send a PR if needed:

    // Install global registry
    const globalRegistry = new CustomElementRegistry();
    Object.defineProperty(window, 'customElements', {
        value: new Proxy(window.customElements, {
            get: (original, prop) => prop in globalRegistry ?
                globalRegistry[prop] :
                original[prop],
        }),
        configurable: true,
        writable: true,
    });
stale[bot] commented 2 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

bicknellr commented 1 year ago

I was talking with @kevinpschaaf yesterday and he discovered this:

https://github.com/jsdom/jsdom/blob/04f6c13f4a4d387c7fc979b8f62c6f68d8a0c639/lib/jsdom/living/helpers/html-constructor.js#L13-L18

It looks like jsdom is grabbing the main registry by reading the .customElements property of the global, which is not something the browser would do. I'm going to try and make a PR for jsdom.