Open josephsintum opened 1 month ago
This is related to #2728 and #2731 , maybe some check is required for special cases like window, document and such or the other way around?
I'm getting the same error, but with a slightly different error message:
DOMException: Failed to execute 'structuredClone' on 'Window': function proxy(a, b) {
return p.invoke(func, this, slice(arguments));
} could not be cloned.
A quick and dirty pseudo-solution:
--- node_modules/@web/dev-server-core/dist/web-sockets/webSocketsPlugin.js.bak 2024-09-10 13:52:55
+++ node_modules/@web/dev-server-core/dist/web-sockets/webSocketsPlugin.js 2024-09-10 13:48:32
@@ -38,7 +38,12 @@
}
export function stable (obj, replacer, spacer) {
- var target = structuredClone(obj)
+ var target;
+ try {
+ target = structuredClone(obj)
+ } catch (e) {
+ target = obj;
+ }
var tmp = deterministicDecirc(target, '', [], undefined) || target
var res
if (replacerStack.length === 0) {
This isn't production code, but at least it lets my tests report correctly, which is much better than waiting for two minutes for a random timeout on a test code that can't timeout.
As a side note, I see the upstream code has been updated over time. The function name stable
has been replaced 6½ years ago.
Before getting into an explanation of the problem, here's a workaround:
@ungap/structured-clone
export default {
// ...
testRunnerHtml(testFramework) {
return <html><body><script type="module">import structuredClone from '@ungap/structured-clone';window.structuredClone = (value) => structuredClone(value, { lossy: true });</script><script type="module" src="${testFramework}"></script></body></html>
;
},
// ...
}
That replaces the browser's built-in structuredClone algorithm with a polyfill that is more forgiving.
Just be aware the diffs shown could be incomplete:
![image](https://github.com/user-attachments/assets/9719def3-30a5-40ab-9896-6c1fb3acbdc5)
Here the function instances differed, but get replaced by undefined before the diff was shown. Better than nothing though.
## The Problem
The root cause appears to be that Chai's ``AssertionError`` has an ``actual`` property, which contains the actual object differing from the ``expected`` one. This ``AssertionError`` (or a shallow copy) is in the data structure that we attempt to clone and serialize:
![swappy-20240916_083339](https://github.com/user-attachments/assets/7e00835f-c46b-443a-9aa9-09e9f9b8ca62)
Obviously this is going to go badly if there's anything in there that can't be cloned/serialized. I believe this is the place creating the error object in that structure: https://github.com/modernweb-dev/web/blob/d5ae228f1f030a58995ac5ac5c51df4e02612981/packages/test-runner-mocha/src/collectTestResults.ts#L49
At the end of the day there's no good *and* easy way out of this, since afaik those properties are used to calculate diffs on the server side, and thus must be sent for that work. Fixing this either requires calculating diffs client-side, or coming up a with a representation of expected/actual objects which cleanly serialize and can be used to calculate diffs without reducing their quality.
I think this is a duplicate of #2772 which I was made aware of
When asserting with and object that contains or reference the window, the test never finish and in the browser it show a structuredClone error in the test framework Here's a test case
The test finishes but gets stuck, in the CLI, there are no errors but in the browser, you can see this error message
DataCloneError: Failed to execute 'structuredClone' on 'Window': function Window() { [native code] } could not be cloned. at stable (__web-dev-server__web-socket.js:23:24)