framework
framework copied to clipboard
feat(test-utils): allow mounting single component for testing
🔗 Linked issue
❓ Type of change
- [ ] 📖 Documentation (updates to the documentation or readme)
- [ ] 🐞 Bug fix (a non-breaking change that fixes an issue)
- [ ] 👌 Enhancement (improving an existing functionality like performance)
- [x] ✨ New feature (a non-breaking change that adds functionality)
- [ ] ⚠️ Breaking change (fix or feature that would cause existing functionality to change)
📚 Description
This PR enables a special route /__nuxt_component_test__/ to mount a single component from everywhere while preserving the Nuxt's pipeline and context. Also added $fetchComponent and componentTestUrl util to @nuxt/test-utils to construct the URL easier.
import { createPage, $fetch, $fetchComponent, componentTestUrl } from '@nuxt/test-utils'
describe('component testing', () => {
it('should work', async () => {
const comp1 = await $fetchComponent('components/SugarCounter.vue', { count: 42 })
expect(comp1).toContain('42 x 2 = 84')
const comp2 = await $fetchComponent('components/SugarCounter.vue', { count: 100 })
expect(comp2).toContain('100 x 2 = 200')
const page = await createPage(componentTestUrl('components/SugarCounter.vue', { count: 42 })
// ....
})
})
Caveat
Since it uses dynamic imports from strings, it will only work on dev mode with Vite + viteNode: true
📝 Checklist
- [x] Basic functionality
- [ ] Mount with user app.vue (with an option?)
- [ ] Add tests with the browser interactions
- [ ] Throw error on non Vite Node env
- [ ] Throw error when the component does not exist
- [ ] Test with Vue Router (should we support it by mocking the router, or we say it would be an anti-pattern to directly use router in components?)
- [ ] Interactive playground (adjust props with UI etc) like Storybook? Could be part of DevTools
Deploy Preview for nuxt3-docs canceled.
| Name | Link |
|---|---|
| Latest commit | 47b5baa362bd9a14e7942503a373aec959875eff |
| Latest deploy log | https://app.netlify.com/sites/nuxt3-docs/deploys/632be8ee3133d400096aa6c7 |
💡 Ideas from @danielroe
- we import and initialize
app.vueto have the side-effects and context but not render it - or we use a test-only transform to inject the slot.
Introducing the side-effects of app.vue is probably not the best idea. It makes implementation more fragile and less consistant with selective-ssr components.
If we are on hold for App.vue side-effects, I think the first MVP is ready for review/discussion and then we can iterate in future PRs.
I'm waiting for a review on this PR for #5689 standardizing universal isolated component rendering API.
App.vue side-effects, I think the first MVP is ready for review/discussion and then we can iterate in future PRs.
Sure. I think generally it is a bad decision but if we want to try can be done in another future PR.
LGTM, thanks!
With nuxt-vitest, this is probably no longer needed?
Providing a way to render a single component using the nuxt pipeline is also helpful in other scenarios like storybook or cypress integration, see eg https://github.com/nuxt/nuxt/issues/18596 and https://github.com/cypress-io/cypress/issues/23619.