Tests for Elm's Virtual DOM with Chrome extensions (Issue).
- Aims to make this tests successful with the latest
elm/html
. - Visit elm-break-dom.netlify.com with problematic extensions enabled/disabled.
npm install
npm run build
This will build two apps (simple.js
and extensions.js
).
Each of those have both version of Browser.application
and Browser.element
.
This will also build patched versions of them (simple-patched.js
and extensions-patched.js
).
They are built with patched version of elm/virtual-dom
using patch/VirtualDom.patch
(See the detail).
npm test
This test breaks DOM in various patterns without real Chrome extensions.
For each test case,
- An element is inserted/removed via ports when a button is clicked.
- Elm will update Virtual DOM. See the source to find where in the DOM is updated in each case.
If you want manual testing, run npm run test:simple-manual
.
(Note: You cannot test after an error is thrown. Reload to test another.)
npm run test:extensions
This test coveres problematic cases of well-known extensions.
Since this test uses the real extensions, it cannot be covered by puppeteer. You need to see the result on your Chrome. Turn on and off the your extensions to see how the results change.
For the case of inserting elements into the top of <body>
, you can try patched version too.
Describing where and when an element is inserted, thanks to the discussion in the discourse thread. More informarion is welcome.
Plugin (Users) | Where in <body> |
When | Workaround (keep enabled) | Workaround (disable) | |
---|---|---|---|---|---|
Google Translate (10,000,000+) | middle | translate the page | <meta name="google" content="notranslate"> in <head> |
||
Google Translate | bottom | select words | rough patch, use Browser.element |
||
Grammarly (10,000,000+) | middle | focus on <textarea> |
data-gramm_editor="false" |
||
Dark Reader (1,763,020) | middle (sometimes) | laod | make <style> the last child, avoid using <style> in <body> |
||
ChromeVox (161,918) | top | load, focus on something | rough patch, use Browser.element |
||
Viber (133,220) | top, bottom | load | rough patch, use Browser.element |
Note:
- For "Where in
<body>
" Column,top
andbottom
breaksBrowser.application
andmiddle
breaks bothBrowser.application
andBrowser.element
.middle
contains modifications to all descendant elements in the<body>
. - Some of the extensions insert elements in
<head>
or after<body>
. They are excluded from this list because it has no harm.
Here is a simple patch (thanks to a discourse comment) for Browser.application
.
root_id=root # Note: <div id="$root_id"> must exist before Elm.Main.init()
cat elm.js\
| sed "s/var bodyNode = _VirtualDom_doc.body;/var bodyNode = _VirtualDom_doc.getElementById('$root_id');/"\
| sed "s/var nextNode = _VirtualDom_node('body')(_List_Nil)(doc.body);/var nextNode = _VirtualDom_node('div')(_List_Nil)(doc.body);/"\
> elm-patched.js
Note: This is just a workaround, NOT a fix. For Browser.application
, the root should be always <body>
element. This is by design.
Note: This will be no use once this patch is merged.
- Better patch
- More extensions