framework icon indicating copy to clipboard operation
framework copied to clipboard

feat(test-utils): allow mounting single component for testing

Open antfu opened this issue 3 years ago • 5 comments

🔗 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

antfu avatar Jul 05 '22 06:07 antfu

Deploy Preview for nuxt3-docs canceled.

Name Link
Latest commit 47b5baa362bd9a14e7942503a373aec959875eff
Latest deploy log https://app.netlify.com/sites/nuxt3-docs/deploys/632be8ee3133d400096aa6c7

netlify[bot] avatar Jul 05 '22 06:07 netlify[bot]

💡 Ideas from @danielroe

  • we import and initialize app.vue to have the side-effects and context but not render it
  • or we use a test-only transform to inject the slot.

antfu avatar Jul 08 '22 09:07 antfu

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.

pi0 avatar Jul 08 '22 09:07 pi0

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.

antfu avatar Jul 15 '22 08:07 antfu

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.

pi0 avatar Jul 15 '22 08:07 pi0

LGTM, thanks!

antfu avatar Feb 04 '23 15:02 antfu

With nuxt-vitest, this is probably no longer needed?

antfu avatar Feb 23 '23 19:02 antfu

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.

tobiasdiez avatar Feb 24 '23 07:02 tobiasdiez