Using `mountSuspended()` with a component using `<script setup>` and `#import` makes an error
Environment
Working directory: /home/projects/jvmibwmjx.github Nuxt project info:
- Operating System: Linux
- Node Version: v18.20.3
- Nuxt Version: 3.12.2
- CLI Version: 3.12.0
- Nitro Version: 2.9.6
- Package Manager: [email protected]
- Builder: -
- User Config: devtools
- Runtime Modules: -
- Build Modules: -
Reproduction
https://stackblitz.com/edit/github-mmtufx?file=app.vue
Describe the bug
Let's say there is a root component which I want to mount using @nuxt/test-utils's mountSuspended() API. If this component
- uses
<script setup> - imports composable API from Nuxt
#import(i.e.useRouter,useRoute, ...)
it makes an error below and breaks entire test.
stdout | createSuspenseBoundary (/home/projects/jvmibwmjx.github/node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:1451:43)
<Suspense> is an experimental feature and its API will likely change.
stderr | warn$1 (/home/projects/jvmibwmjx.github/node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:50:13)
[Vue warn]: Cannot mutate <script setup> binding "useRouter" from Options API.
at <MountSuspendedComponent >
at <MountSuspendedHelper>
at <Anonymous ref="VTU_COMPONENT" >
at <VTUROOT>
[Vue warn]: Unhandled error during execution of render function
at <MountSuspendedComponent >
at <MountSuspendedHelper>
at <Anonymous ref="VTU_COMPONENT" >
at <VTUROOT>
Only if the root component meets the condition above, the issue occurs. As you see in the reproduction, if you use #imports and <script setup> in child elements it work fine.
The app itself is built and works fine if I run it.
You can reproduce the issue with the repository link above.
Additional context
No response
Logs
No response
FYI @danielroe
To resolve the issue with mountSuspended() when using a root component with <script setup> and #import for composable APIs from Nuxt, you need to ensure that the setup function is properly wrapped and executed within the Nuxt environment. Here are the steps to address this:
-
Wrap the
setupfunction: Ensure that thesetupfunction is properly wrapped to handle the Nuxt environment. -
Initialize the Nuxt environment: Make sure the Nuxt environment is correctly initialized before running your tests.
Here is an example of how you can achieve this:
import { mountSuspended } from '@nuxt/test-utils'
import { defineNuxtComponent, tryUseNuxtApp } from '#app'
import { h } from 'vue'
const wrappedSetup = async (props, setupContext) => {
let setupState = {}
if (setup) {
const result = await setup(props, setupContext)
setupState = result && typeof result === 'object' ? result : {}
return result
}
}
const vueApp = tryUseNuxtApp()?.vueApp || globalThis.__unctx__.get('nuxt-app').tryUse().vueApp
const wrapper = await mountSuspended(defineNuxtComponent({
setup: wrappedSetup,
render: () => h('div', 'hi there'),
}))
expect(wrapper.html()).toMatchInlineSnapshot('"<div>hi there</div>"')
This code ensures that the setup function is properly handled and the Nuxt environment is correctly initialized. Additionally, you can refer to the test/nuxt/composables.test.ts file for more examples on how to test various composables within the Nuxt environment [1][2].
If you are still encountering issues, ensure that your component and its dependencies are correctly set up and that the Nuxt environment is properly initialized before running your tests.
@danielroe, this one's a bit out of my wheelhouse, could you step in and provide your guidance?
To continue talking to Dosu, mention @dosu.
Is there any update on this? I'm getting a very similar error in my tests, and the workaround above does not seem feasible to be included in a simple test.
I am running into the same issue. It's the only component/test running into this, despite all of them using <script setup lang="ts">.
<script lang="ts" setup>
const {
label,
error,
helpText,
id = 'input',
} = defineProps<{
label?: string;
error?: string;
helpText?: string;
id?: string;
}>();
const modelValue = defineModel<string | number>();
const attrs = useAttrs();
</script>
[Vue warn]: Cannot mutate <script setup> binding "error" from Options API.
Possibly the same issue as #744? Any updates for this or that? @danielroe
Related bug report: https://github.com/nuxt/test-utils/issues/986
I have triaged this and renderSuspended starts getting this issue from v13.14.0.
@ngajhede In your case it's breaking since you're using the prop name error.
resolved in https://github.com/nuxt/test-utils/commit/4e9f34b96ac5432cc9429aadfa07c3503dffbf15
@danielroe sorry to revive this, but even with 3.15.4 when I have a prop named results with mountSuspended I still get the warning
[Vue warn]: Cannot mutate
A prop named error seems to be working though.
3.16.1 I'm getting this with a prop name error if I rename that, it works just fine