svelte-testing-library icon indicating copy to clipboard operation
svelte-testing-library copied to clipboard

Happy-DOM on svelte5 branch causes PrettyFormatPluginError when rendering 1 line

Open sureshjoshi opened this issue 1 year ago • 3 comments

I made a brief comment on #284 - but I thought I could add a partial reproduction step. I wasn't able to cause this on main - so I don't know if it's related to svelte5, or the fact that the happy-dom commits haven't been merged. Either way, it took me hours to dig in and debug this - so hopefully this will help anyone else running down this path.

On the svelte5 branch, I created a mostly empty Svelte component:

<!-- EmptyComp.svelte -->
<h1>Hello world!</h1>

and I modified the debug.test.js to point to this:

import { describe, test } from 'vitest'
import { render } from '..'
import EmptyComp from './fixtures/EmptyComp.svelte'

describe('debug', () => {
  test('pretty prints the container', () => {
    const { debug } = render(EmptyComp)
    debug()
  })
})

Running test using jsdom, and there are no problems - passes.

Installing the latest happy-dom and running test returns this PrettyFormatPluginError.

PrettyFormatPluginError: Cannot read properties of null (reading 'toLowerCase')
 ❯ Object.serialize node_modules/.pnpm/@[email protected]/node_modules/@testing-library/dom/dist/@testing-library/dom.esm.js:107:77

 ❯ printPlugin node_modules/.pnpm/[email protected]/node_modules/pretty-format/build/index.js:330:16
 ❯ printer node_modules/.pnpm/[email protected]/node_modules/pretty-format/build/index.js:379:12
 ❯ node_modules/.pnpm/@[email protected]/node_modules/@testing-library/dom/dist/@testing-library/dom.esm.js:43:79
 ❯ printChildren node_modules/.pnpm/@[email protected]/node_modules/@testing-library/dom/dist/@testing-library/dom.esm.js:42:89
 ❯ Object.serialize node_modules/.pnpm/@[email protected]/node_modules/@testing-library/dom/dist/@testing-library/dom.esm.js:114:75
 ❯ printPlugin node_modules/.pnpm/[email protected]/node_modules/pretty-format/build/index.js:330:16
 ❯ printer node_modules/.pnpm/[email protected]/node_modules/pretty-format/build/index.js:379:12
 ❯ node_modules/.pnpm/@[email protected]/node_modules/@testing-library/dom/dist/@testing-library/dom.esm.js:43:79

What's weird is that, if there are 2 HTML lines in the component, the error goes away 🤦🏽

<!-- EmptyComp.svelte -->
<h1>Hello world!</h1>
<h1>Hello world!</h1>

sureshjoshi avatar Feb 06 '24 16:02 sureshjoshi

Upon some searching last night (and just now), I found this ticket about happy-dom tests failing with > 2 components in a file.

https://github.com/sveltejs/svelte/issues/10358

Based on the content of that ticket, I'm now thinking this is more a svelte bug? But it passes in JSDom, so would that make it a happy-dom bug?

Anyways, opening for posterity, and with the hope someone smarter than me can enlighten me 😄

sureshjoshi avatar Feb 06 '24 16:02 sureshjoshi

Thanks for the heads up @sureshjoshi, this is weird! I agree, I don't think it's a bug with anything we're doing here. For now, I've put up a newer Svelte 5 branch - https://github.com/testing-library/svelte-testing-library/pull/321 - so we can at least see this failure in our CI matrix

mcous avatar Feb 12 '24 01:02 mcous

Yeah, feels like a Svelte issue - but it's good to track in the hopes that it'll get fixed in one of these Svelte Next's

sureshjoshi avatar Feb 13 '24 22:02 sureshjoshi

This issue is suspiciously similar to #343. In the case of that issue, I was actually able to identify the causes in the Svelte and Happy DOM codebases. I'm still struggling to find a cause for this issue here, but due to some interaction between these two libraries, Element's are getting created (or updated) with their tagName property set to null

mcous avatar Apr 02 '24 15:04 mcous

Alright, pretty sure I've found found the cause:

  • Svelte 5 makes various DOM operation calls through Node.prototype and Element.prototype for performance, including cloneNode
  • Because of the way Happy DOM uses classes and inheritance, this doesn't work at all

Given the Svelte code in question works happily in the browser, I think this is a Happy DOM bug. But to my eyes, it also looks like a large architectural change to fix on the Happy DOM side, which is pretty unfortunate

mcous avatar Apr 06 '24 17:04 mcous

Wow... Okay, well... That's something for sure. Thanks for the investigation! I guess it's JSDom for me for the near-future

sureshjoshi avatar Apr 06 '24 18:04 sureshjoshi

Just kidding, the happy-dom maintainers are on top of their stuff! [email protected] has been released and it resolves the issue. Our happy-dom test suite is now passing on Svelte 5

mcous avatar Apr 07 '24 15:04 mcous

Hooray! I didn't even have enough time to pn install before they fixed it :)

sureshjoshi avatar Apr 07 '24 17:04 sureshjoshi

:tada: This issue has been resolved in version 4.2.3 :tada:

The release is available on:

Your semantic-release bot :package::rocket:

github-actions[bot] avatar Apr 18 '24 15:04 github-actions[bot]

@yanick another one bites the dust! Not sure why semantic release didn't catch this one, but this issue has been resolved upstream and can be closed

mcous avatar Apr 18 '24 16:04 mcous

W00t!

yanick avatar Apr 18 '24 16:04 yanick