-
Notifications
You must be signed in to change notification settings - Fork 331
Description
- Dusk Version: 6.22
- Laravel Version: 8.33.5
- PHP Version: 7.4.24
- Database Driver & Version: mysql 5.7
Description:
assertVue does not work on vue 3 in some cases due to the presence of $vnode and $root in the ctx object,
because it tries to json encode it which can cause an error "Converting circular structure to JSON"
It seems that keeping the app instance globally like for example with a mixin trigger the issue
Steps To Reproduce:
create a hello-word project
vue create hello-world
create a circular reference in the main.js, for example with a mixin that makes the app object globally available :
let app = createApp(App)
app.mixin({
beforeCreate() {
this.$app = app;
}
})
app.mount('#app')
in console :
JSON.stringify(document.querySelector('.hello').__vueParentComponent.ctx)
it should trigger something like that :
Uncaught (in promise) TypeError: Converting circular structure to JSON
--> starting at object with constructor 'Object'
| property 'component' -> object with constructor 'Object'
--- property 'vnode' closes the circle
the error is in vueAttribute method :
public function vueAttribute($componentSelector, $key)
{
$fullSelector = $this->resolver->format($componentSelector);
return $this->driver->executeScript(
"var el = document.querySelector('".$fullSelector."');".
"return typeof el.__vue__ === 'undefined' ".
'? JSON.parse(JSON.stringify(el.__vueParentComponent.ctx)).'.$key.
': el.__vue__.'.$key
);
}
here is th PR that added vue 3 support : #968
it might be safer to remove $root and $vnode before JSON.stringify
in my side, the fix i did is that :
app.mixin({
beforeCreate() {
this.$getApp = () => {
return app;
}
}
})
it prevent any circular reference.
i'm doing that because i need a better way to retrieve the vue instance than using getCurrentInstance which can return null in some contexts
thanks.