{
  "doc": {
    "id": "app/component-testing/vue/examples",
    "title": "Vue Examples",
    "description": "Examples for testing Vue components with Cypress.",
    "section": "app",
    "source_path": "/llm/markdown/app/component-testing/vue/examples.md",
    "version": "24a73f8a97175663aaffd3b016289fb2a523a4ea",
    "updated_at": "2026-05-14T20:17:33.301Z",
    "headings": [
      {
        "id": "app/component-testing/vue/examples#vue-examples",
        "text": "Vue Examples",
        "level": 1
      },
      {
        "id": "app/component-testing/vue/examples#what-youll-learn",
        "text": "What you'll learn",
        "level": 5
      },
      {
        "id": "app/component-testing/vue/examples#mounting-components",
        "text": "Mounting Components",
        "level": 2
      },
      {
        "id": "app/component-testing/vue/examples#using-cy-mount",
        "text": "Using cy.mount()",
        "level": 3
      },
      {
        "id": "app/component-testing/vue/examples#passing-data-to-a-component",
        "text": "Passing Data to a Component",
        "level": 3
      },
      {
        "id": "app/component-testing/vue/examples#testing-event-handlers",
        "text": "Testing Event Handlers",
        "level": 3
      },
      {
        "id": "app/component-testing/vue/examples#using-jsx",
        "text": "Using JSX",
        "level": 3
      },
      {
        "id": "app/component-testing/vue/examples#using-slots",
        "text": "Using Slots",
        "level": 2
      },
      {
        "id": "app/component-testing/vue/examples#default-slot",
        "text": "Default Slot",
        "level": 3
      },
      {
        "id": "app/component-testing/vue/examples#named-slot",
        "text": "Named Slot",
        "level": 3
      },
      {
        "id": "app/component-testing/vue/examples#using-vue-test-utils",
        "text": "Using Vue Test Utils",
        "level": 2
      },
      {
        "id": "app/component-testing/vue/examples#custom-mount-commands",
        "text": "Custom Mount Commands",
        "level": 2
      },
      {
        "id": "app/component-testing/vue/examples#customizing-cy-mount",
        "text": "Customizing cy.mount()",
        "level": 3
      },
      {
        "id": "app/component-testing/vue/examples#replicating-plugins",
        "text": "Replicating Plugins",
        "level": 3
      },
      {
        "id": "app/component-testing/vue/examples#replicating-the-expected-component-hierarchy",
        "text": "Replicating the expected Component Hierarchy",
        "level": 3
      },
      {
        "id": "app/component-testing/vue/examples#vue-router",
        "text": "Vue Router",
        "level": 3
      },
      {
        "id": "app/component-testing/vue/examples#vuex",
        "text": "Vuex",
        "level": 3
      },
      {
        "id": "app/component-testing/vue/examples#global-components",
        "text": "Global Components",
        "level": 3
      }
    ]
  },
  "chunks": [
    {
      "id": "app/component-testing/vue/examples#what-youll-learn",
      "doc_id": "app/component-testing/vue/examples",
      "heading": "What you'll learn",
      "heading_level": 5,
      "content_markdown": "##### What you'll learn\n\n*   How to mount Vue components in Cypress\n*   How to pass props and events to components\n*   How to use slots in components\n*   How to use Vue Test Utils with Cypress\n*   How to customize `cy.mount()` with Vue\n",
      "section": "app",
      "anchors": [
        "what-youll-learn"
      ],
      "path": "/llm/json/chunked/app/component-testing/vue/examples.json",
      "token_estimate": 59
    },
    {
      "id": "app/component-testing/vue/examples#mounting-components",
      "doc_id": "app/component-testing/vue/examples",
      "heading": "Mounting Components",
      "heading_level": 2,
      "content_markdown": "## Mounting Components\n\n### Using `cy.mount()`\n\nTo mount a component with `cy.mount()`, import the component and pass it to the method:\n\n```\nimport { Stepper } from './Stepper.vue'it('mounts', () => {  cy.mount(Stepper)})\n```\n\n### Passing Data to a Component\n\nYou can pass props and events to a component by setting `props` in the options:\n\n```\ncy.mount(Stepper, {  props: {    initial: 100,  },})\n```\n\n### Testing Event Handlers\n\nPass a Cypress [spy](/llm/markdown/app/guides/stubs-spies-and-clocks.md#Spies) to an event prop and validate it was called:\n\n```\nit('clicking + fires a change event with the incremented value', () => {  const onChangeSpy = cy.spy().as('onChangeSpy')  cy.mount(Stepper, { props: { onChange: onChangeSpy } })  cy.get('[data-cy=increment]').click()  cy.get('@onChangeSpy').should('have.been.calledWith', 1)})\n```\n\n### Using JSX\n\nThe mount command also supports JSX syntax (provided that you've configured your bundler to support transpiling JSX or TSX files). Some might find using JSX syntax beneficial when writing tests.\n\nSample with JSX:\n\n```\nit('clicking + fires a change event with the incremented value', () => {  const onChangeSpy = cy.spy().as('onChangeSpy')  cy.mount(<Stepper initial={100} onChange={onChangeSpy} />)  cy.get('[data-cy=increment]').click()  cy.get('@onChangeSpy').should('have.been.calledWith', 101)})\n```\n",
      "section": "app",
      "anchors": [
        "mounting-components"
      ],
      "path": "/llm/json/chunked/app/component-testing/vue/examples.json",
      "token_estimate": 229
    },
    {
      "id": "app/component-testing/vue/examples#using-cy-mount",
      "doc_id": "app/component-testing/vue/examples",
      "heading": "Using cy.mount()",
      "heading_level": 3,
      "content_markdown": "### Using `cy.mount()`\n\nTo mount a component with `cy.mount()`, import the component and pass it to the method:\n\n```\nimport { Stepper } from './Stepper.vue'it('mounts', () => {  cy.mount(Stepper)})\n```\n",
      "section": "app",
      "anchors": [
        "using-cy-mount"
      ],
      "path": "/llm/json/chunked/app/component-testing/vue/examples.json",
      "token_estimate": 40
    },
    {
      "id": "app/component-testing/vue/examples#passing-data-to-a-component",
      "doc_id": "app/component-testing/vue/examples",
      "heading": "Passing Data to a Component",
      "heading_level": 3,
      "content_markdown": "### Passing Data to a Component\n\nYou can pass props and events to a component by setting `props` in the options:\n\n```\ncy.mount(Stepper, {  props: {    initial: 100,  },})\n```\n",
      "section": "app",
      "anchors": [
        "passing-data-to-a-component"
      ],
      "path": "/llm/json/chunked/app/component-testing/vue/examples.json",
      "token_estimate": 40
    },
    {
      "id": "app/component-testing/vue/examples#testing-event-handlers",
      "doc_id": "app/component-testing/vue/examples",
      "heading": "Testing Event Handlers",
      "heading_level": 3,
      "content_markdown": "### Testing Event Handlers\n\nPass a Cypress [spy](/llm/markdown/app/guides/stubs-spies-and-clocks.md#Spies) to an event prop and validate it was called:\n\n```\nit('clicking + fires a change event with the incremented value', () => {  const onChangeSpy = cy.spy().as('onChangeSpy')  cy.mount(Stepper, { props: { onChange: onChangeSpy } })  cy.get('[data-cy=increment]').click()  cy.get('@onChangeSpy').should('have.been.calledWith', 1)})\n```\n",
      "section": "app",
      "anchors": [
        "testing-event-handlers"
      ],
      "path": "/llm/json/chunked/app/component-testing/vue/examples.json",
      "token_estimate": 63
    },
    {
      "id": "app/component-testing/vue/examples#using-jsx",
      "doc_id": "app/component-testing/vue/examples",
      "heading": "Using JSX",
      "heading_level": 3,
      "content_markdown": "### Using JSX\n\nThe mount command also supports JSX syntax (provided that you've configured your bundler to support transpiling JSX or TSX files). Some might find using JSX syntax beneficial when writing tests.\n\nSample with JSX:\n\n```\nit('clicking + fires a change event with the incremented value', () => {  const onChangeSpy = cy.spy().as('onChangeSpy')  cy.mount(<Stepper initial={100} onChange={onChangeSpy} />)  cy.get('[data-cy=increment]').click()  cy.get('@onChangeSpy').should('have.been.calledWith', 101)})\n```\n",
      "section": "app",
      "anchors": [
        "using-jsx"
      ],
      "path": "/llm/json/chunked/app/component-testing/vue/examples.json",
      "token_estimate": 83
    },
    {
      "id": "app/component-testing/vue/examples#using-slots",
      "doc_id": "app/component-testing/vue/examples",
      "heading": "Using Slots",
      "heading_level": 2,
      "content_markdown": "## Using Slots\n\n### Default Slot\n\n*   DefaultSlot.cy.js\n*   DefaultSlot.cy.jsx (JSX)\n*   DefaultSlot.vue\n\n```\nimport DefaultSlot from './DefaultSlot.vue'describe('<DefaultSlot />', () => {  it('renders', () => {    cy.mount(DefaultSlot, {      slots: {        default: 'Hello there!',      },    })    cy.get('div.content').should('have.text', 'Hello there!')  })})\n```\n\n```\nimport DefaultSlot from './DefaultSlot.vue'describe('<DefaultSlot />', () => {  it('renders', () => {    cy.mount(<DefaultSlot>Hello there!</DefaultSlot>)    cy.get('div.content').should('have.text', 'Hello there!')  })})\n```\n\n```\n<template>  <div>    <div class=\"content\">      <slot />    </div>  </div></template><script setup></script>\n```\n\n### Named Slot\n\n*   NamedSlot.cy.js\n*   NamedSlot.cy.jsx (JSX)\n*   NamedSlot.vue\n\n```\nimport NamedSlot from './NamedSlot.vue'describe('<NamedSlot />', () => {  it('renders', () => {    const slots = {      header: 'my header',      footer: 'my footer',    }    cy.mount(NamedSlot, {      slots,    })    cy.get('header').should('have.text', 'my header')    cy.get('footer').should('have.text', 'my footer')  })})\n```\n\n```\nimport NamedSlot from './NamedSlot.vue'describe('<NamedSlot />', () => {  it('renders', () => {    const slots = {      header: 'my header',      footer: 'my footer',    }    cy.mount(<NamedSlot>{{ ...slots }}</NamedSlot>)    cy.get('header').should('have.text', 'my header')    cy.get('footer').should('have.text', 'my footer')  })})\n```\n\n```\n<template>  <div>    <header>      <slot name=\"header\" />    </header>    <footer>      <slot name=\"footer\" />    </footer>  </div></template><script setup></script>\n```\n\nFor more info on testing Vue components with slots, refer to the [Vue Test Utils Slots guide](https://test-utils.vuejs.org/guide/advanced/slots.html).\n",
      "section": "app",
      "anchors": [
        "using-slots"
      ],
      "path": "/llm/json/chunked/app/component-testing/vue/examples.json",
      "token_estimate": 247
    },
    {
      "id": "app/component-testing/vue/examples#default-slot",
      "doc_id": "app/component-testing/vue/examples",
      "heading": "Default Slot",
      "heading_level": 3,
      "content_markdown": "### Default Slot\n\n*   DefaultSlot.cy.js\n*   DefaultSlot.cy.jsx (JSX)\n*   DefaultSlot.vue\n\n```\nimport DefaultSlot from './DefaultSlot.vue'describe('<DefaultSlot />', () => {  it('renders', () => {    cy.mount(DefaultSlot, {      slots: {        default: 'Hello there!',      },    })    cy.get('div.content').should('have.text', 'Hello there!')  })})\n```\n\n```\nimport DefaultSlot from './DefaultSlot.vue'describe('<DefaultSlot />', () => {  it('renders', () => {    cy.mount(<DefaultSlot>Hello there!</DefaultSlot>)    cy.get('div.content').should('have.text', 'Hello there!')  })})\n```\n\n```\n<template>  <div>    <div class=\"content\">      <slot />    </div>  </div></template><script setup></script>\n```\n",
      "section": "app",
      "anchors": [
        "default-slot"
      ],
      "path": "/llm/json/chunked/app/component-testing/vue/examples.json",
      "token_estimate": 91
    },
    {
      "id": "app/component-testing/vue/examples#named-slot",
      "doc_id": "app/component-testing/vue/examples",
      "heading": "Named Slot",
      "heading_level": 3,
      "content_markdown": "### Named Slot\n\n*   NamedSlot.cy.js\n*   NamedSlot.cy.jsx (JSX)\n*   NamedSlot.vue\n\n```\nimport NamedSlot from './NamedSlot.vue'describe('<NamedSlot />', () => {  it('renders', () => {    const slots = {      header: 'my header',      footer: 'my footer',    }    cy.mount(NamedSlot, {      slots,    })    cy.get('header').should('have.text', 'my header')    cy.get('footer').should('have.text', 'my footer')  })})\n```\n\n```\nimport NamedSlot from './NamedSlot.vue'describe('<NamedSlot />', () => {  it('renders', () => {    const slots = {      header: 'my header',      footer: 'my footer',    }    cy.mount(<NamedSlot>{{ ...slots }}</NamedSlot>)    cy.get('header').should('have.text', 'my header')    cy.get('footer').should('have.text', 'my footer')  })})\n```\n\n```\n<template>  <div>    <header>      <slot name=\"header\" />    </header>    <footer>      <slot name=\"footer\" />    </footer>  </div></template><script setup></script>\n```\n\nFor more info on testing Vue components with slots, refer to the [Vue Test Utils Slots guide](https://test-utils.vuejs.org/guide/advanced/slots.html).\n",
      "section": "app",
      "anchors": [
        "named-slot"
      ],
      "path": "/llm/json/chunked/app/component-testing/vue/examples.json",
      "token_estimate": 152
    },
    {
      "id": "app/component-testing/vue/examples#using-vue-test-utils",
      "doc_id": "app/component-testing/vue/examples",
      "heading": "Using Vue Test Utils",
      "heading_level": 2,
      "content_markdown": "## Using Vue Test Utils\n\nIn order to encourage interoperability between your existing component tests and Cypress, we support using Vue Test Utils' API.\n\n```\ncy.mount(Stepper).then(({ wrapper, component }) => {  // `wrapper` is the Vue Test Utils wrapper  // `component` is the component instance itself})\n```\n\nIf you intend to use the `wrapper` frequently and use Vue Test Util's API, we recommend you write a [custom mount command](/llm/markdown/api/commands/mount.md) and create a Cypress alias to get back at the `wrapper`.\n\n```\nimport { mount } from 'cypress/vue'Cypress.Commands.add('mount', (...args) => {  return mount(...args).then(({ wrapper }) => {    return cy.wrap(wrapper).as('vue')  })})// the \"@vue\" alias will now work anywhere// after you've mounted your componentcy.mount(Stepper).doStuff().get('@vue') // The subject is now the Vue Wrapper\n```\n\nThis means that you are able to get to the resulting `wrapper` returned from the `mount` command and use `wrapper.emitted()` in order to gain access to Native DOM events that were fired, as well as custom events that were emitted by your component under test.\n\nBecause `wrapper.emitted()` is only data, and NOT spy-based you will have to unpack its results to write assertions.\n\nYour test failure messages will not be as helpful because you're not able to use the Sinon-Chai library that Cypress ships, which comes with methods such as `to.have.been.called` and `to.have.been.calledWith`.\n\nUsage of the `cy.get('@vue')` alias may look something like the below code snippet.\n\nNotice that we're using the `'should'` function signature in order to take advantage of Cypress's [retryability](/llm/markdown/app/guides/test-retries.md). If we chained using `cy.then` instead of `cy.should`, we may run into the kinds of issues you have in Vue Test Utils tests where you have to use `await` frequently in order to make sure the DOM has updated or any reactive events have fired.\n\n*   With emitted\n*   With spies\n\n```\ncy.mount(Stepper, { props: { initial: 100 } })cy.get(incrementSelector).click()cy.get('@vue').should(({ wrapper }) => {  expect(wrapper.emitted('change')).to.have.length  expect(wrapper.emitted('change')[0][0]).to.equal('101')})\n```\n\n```\nconst onChangeSpy = cy.spy().as('onChangeSpy')cy.mount(Stepper, { props: { initial: 100, onChange: onChangeSpy } })cy.get(incrementSelector).click()cy.get('@onChangeSpy').should('have.been.calledWith', '101')\n```\n\nRegardless of our recommendation to use spies instead of the internal Vue Test Utils API, you may decide to continue using `emitted` as it _automatically_ records every single event emitted from the component, and so you won't have to create a spy for every event emitted.\n\nThis auto-spying behavior could be useful for components that emit _many_ custom events.\n",
      "section": "app",
      "anchors": [
        "using-vue-test-utils"
      ],
      "path": "/llm/json/chunked/app/component-testing/vue/examples.json",
      "token_estimate": 512
    },
    {
      "id": "app/component-testing/vue/examples#custom-mount-commands",
      "doc_id": "app/component-testing/vue/examples",
      "heading": "Custom Mount Commands",
      "heading_level": 2,
      "content_markdown": "## Custom Mount Commands\n\n### Customizing `cy.mount()`\n\nWhile you can use the [mount()](/llm/markdown/app/component-testing/vue/api.md#mount) function in your tests, we recommend using [`cy.mount()`](/llm/markdown/api/commands/mount.md), which is a [custom command](/llm/markdown/api/cypress-api/custom-commands.md) that is defined in the **cypress/support/component.js** file:\n\n```\nimport { mount } from 'cypress/vue'Cypress.Commands.add('mount', mount)\n```\n\nThis allows you to use `cy.mount()` in any test without having to import the `mount()` function in each and every spec file.\n\nBy default, `cy.mount()` is a simple passthrough to `mount()`, however, you can customize `cy.mount()` to fit your needs. For instance, if you are using plugins or other global app-level setups in your Vue app, you can configure them here.\n\nBelow are a few examples that demonstrate using a custom mount command. These examples can be adjusted for most other providers that you will need to support.\n\n### Replicating Plugins\n\nMost applications will have state management or routing. Both of these are Vue plugins.\n\n*   cypress/support/component.js\n*   With JSX\n\n```\nimport { createPinia } from 'pinia' // or Vueximport { createI18n } from 'vue-i18n'import { mount } from 'cypress/vue'import { h } from 'vue'// We recommend that you pull this out// into a constants file that you share with// your main.js file.const i18nOptions = {  locale: 'en',  messages: {    en: {      hello: 'hello!',    },    ja: {      hello: 'こんにちは！',    },  },}Cypress.Commands.add('mount', (component, ...args) => {  args.global = args.global || {}  args.global.plugins = args.global.plugins || []  args.global.plugins.push(createPinia())  args.global.plugins.push(createI18n())  return mount(    () => {      return h(VApp, {}, component)    },    ...args  )})\n```\n\n```\nimport { createPinia } from 'pinia' // or Vueximport { createI18n } from 'vue-i18n'import { mount } from 'cypress/vue'// We recommend that you pull this out// into a constants file that you share with// your main.js file.const i18nOptions = {  locale: 'en',  messages: {    en: {      hello: 'hello!',    },    ja: {      hello: 'こんにちは！',    },  },}Cypress.Commands.add('mount', (component, ...args) => {  args.global = args.global || {}  args.global.plugins = args.global.plugins || []  args.global.plugins.push(createPinia())  args.global.plugins.push(createI18n())  // <component> is a built-in component that comes with Vue  return mount(    () => (      <VApp>        <component is={component} />      </VApp>    ),    ...args  )})\n```\n\n### Replicating the expected Component Hierarchy\n\nSome Vue applications, most famously Vue apps built on top of Vuetify, require certain components to be structured in a specific hierarchy.\n\nAll Vuetify applications require that you wrap your app in a `VApp` component when you build it. This is an implementation detail of Vuetify, but once users try to test components that depend on Vuetify, they get Vuetify-specific compilation errors and quickly find out that **they need to replicate that component hierarchy any time they need to mount a component that uses a Vuetify component**!\n\nCustom `cy.mount` commands to the rescue! You may find the JSX syntax to be more straightforward.\n\nYou'll also need to replicate the plugin setup steps from the Vuetify docs for everything to compile.\n\n*   cypress/support/component.js\n*   With JSX\n\n```\nimport Vuetify from 'vuetify/lib'import { VApp } from 'vuetify'import { mount } from 'cypress/vue'import { h } from 'vue'// We recommend that you pull this out// into a constants file that you share with// your main.js file.const vuetifyOptions = {}Cypress.Commands.add('mount', (component, ...args) => {  args.global = args.global || {}  args.global.plugins = args.global.plugins || []  args.global.plugins.push(new Vuetify(vuetifyOptions))  return mount(    () => {      return h(VApp, {}, component)    },    ...args  )})\n```\n\n```\nimport Vuetify from 'vuetify/lib'import { VApp } from 'vuetify'import { mount } from 'cypress/vue'// We recommend that you pull this out// into a constants file that you share with// your main.js file.const vuetifyOptions = {}Cypress.Commands.add('mount', (component, ...args) => {  args.global = args.global || {}  args.global.plugins = args.global.plugins || []  args.global.plugins.push(new Vuetify(vuetifyOptions))  // <component> is a built-in component that comes with Vue  return mount(    () => (      <VApp>        <component is={component} />      </VApp>    ),    ...args  )})\n```\n\n### Vue Router\n\nTo use Vue Router, create a command to register the plugin and pass in a custom implementation of the router via the options param.\n\n*   cypress/support/component.js\n*   Typings\n*   Spec Usage\n\n```\nimport { mount } from 'cypress/vue'import { createMemoryHistory, createRouter } from 'vue-router'import { routes } from '../../src/router'Cypress.Commands.add('mount', (component, options = {}) => {  // Setup options object  options.global = options.global || {}  options.global.plugins = options.global.plugins || []  // create router if one is not provided  if (!options.router) {    options.router = createRouter({      routes: routes,      history: createMemoryHistory(),    })  }  // Add router plugin  options.global.plugins.push({    install(app) {      app.use(options.router)    },  })  return mount(component, options)})\n```\n\n```\nimport { mount } from 'cypress/vue'import { Router } from 'vue-router'type MountParams = Parameters<typeof mount>type OptionsParam = MountParams[1] & { router?: Router }declare global {  namespace Cypress {    interface Chainable {      /**       * Helper mount function for Vue Components       * @param component Vue Component or JSX Element to mount       * @param options Options passed to Vue Test Utils       */      mount(component: any, options?: OptionsParam): Chainable<any>    }  }}\n```\n\n```\nimport Navigation from './Navigation.vue'import { routes } from '../router'import { createMemoryHistory, createRouter } from 'vue-router'it('home link should be active when url is \"/\"', () => {  // No need to pass in custom router as default url is '/'  cy.mount(<Navigation />)  cy.get('a').contains('Home').should('have.class', 'router-link-active')})it('login link should be active when url is \"/login\"', () => {  // Create a new router instance for each test  const router = createRouter({    routes: routes,    history: createMemoryHistory(),  })  // Change location to `/login`,  // and await on the promise with cy.wrap  cy.wrap(router.push('/login'))  // Pass the already initialized router for use  cy.mount(<Navigation />, { router })  cy.get('a').contains('Login').should('have.class', 'router-link-active')})\n```\n\nCalling `router.push()` in the router for Vue 3 is an asynchronous operation. Use the [cy.wrap](/llm/markdown/api/commands/wrap.md) command to have Cypress await the promise's resolve before it continues with other commands:\n\n### Vuex\n\nTo use a component that uses [Vuex](https://vuex.vuejs.org/), create a `mount` command that configures a Vuex store for your component.\n\n*   cypress/support/component.js\n*   Typings\n*   Spec Usage\n\n```\nimport { mount } from 'cypress/vue'import { getStore } from '../../src/plugins/store'Cypress.Commands.add('mount', (component, options = {}) => {  // Setup options object  options.global = options.global || {}  options.global.stubs = options.global.stubs || {}  options.global.stubs['transition'] = false  options.global.components = options.global.components || {}  options.global.plugins = options.global.plugins || []  // Use store passed in from options, or initialize a new one  const { store = getStore(), ...mountOptions } = options  // Add Vuex plugin  options.global.plugins.push({    install(app) {      app.use(store)    },  })  return mount(component, mountOptions)})\n```\n\nThe `getStore` method is a factory method that initializes Vuex and creates a new store. It is important that the store be initialized with each new test to ensure changes to the store don't affect other tests.\n\n```\nimport { mount } from 'cypress/vue'import { Store } from 'vuex'type MountParams = Parameters<typeof mount>type OptionsParam = MountParams[1]declare global {  namespace Cypress {    interface Chainable {      /**       * Helper mount function for Vue Components       * @param component Vue Component or JSX Element to mount       * @param options Options passed to Vue Test Utils       */      mount(        component: any,        options?: OptionsParam & { store?: Store }      ): Chainable<any>    }  }}\n```\n\n```\nimport { getStore } from '@/plugins/store'import UserProfile from './UserProfile.vue'it.only('User profile should display user name', () => {  const user = { name: 'test person' }  // getStore is a factory method that creates a new store  const store = getStore()  // mutate the store with user  store.commit('setUser', user)  cy.mount(UserProfile, {    store,  })  cy.get('div.name').should('have.text', user.name)})\n```\n\n### Global Components\n\nIf you have components that are registered globally in the main application file, set them up in your mount command so your component will render them properly:\n\n```\nimport { mount } from 'cypress/vue'import Button from '../../src/components/Button.vue'Cypress.Commands.add('mount', (component, options = {}) => {  // Setup options object  options.global = options.global || {}  options.global.components = options.global.components || {}  // Register global components  options.global.components['Button'] = Button  return mount(component, options)})\n```\n",
      "section": "app",
      "anchors": [
        "custom-mount-commands"
      ],
      "path": "/llm/json/chunked/app/component-testing/vue/examples.json",
      "token_estimate": 1684
    },
    {
      "id": "app/component-testing/vue/examples#customizing-cy-mount",
      "doc_id": "app/component-testing/vue/examples",
      "heading": "Customizing cy.mount()",
      "heading_level": 3,
      "content_markdown": "### Customizing `cy.mount()`\n\nWhile you can use the [mount()](/llm/markdown/app/component-testing/vue/api.md#mount) function in your tests, we recommend using [`cy.mount()`](/llm/markdown/api/commands/mount.md), which is a [custom command](/llm/markdown/api/cypress-api/custom-commands.md) that is defined in the **cypress/support/component.js** file:\n\n```\nimport { mount } from 'cypress/vue'Cypress.Commands.add('mount', mount)\n```\n\nThis allows you to use `cy.mount()` in any test without having to import the `mount()` function in each and every spec file.\n\nBy default, `cy.mount()` is a simple passthrough to `mount()`, however, you can customize `cy.mount()` to fit your needs. For instance, if you are using plugins or other global app-level setups in your Vue app, you can configure them here.\n\nBelow are a few examples that demonstrate using a custom mount command. These examples can be adjusted for most other providers that you will need to support.\n",
      "section": "app",
      "anchors": [
        "customizing-cy-mount"
      ],
      "path": "/llm/json/chunked/app/component-testing/vue/examples.json",
      "token_estimate": 168
    },
    {
      "id": "app/component-testing/vue/examples#replicating-plugins",
      "doc_id": "app/component-testing/vue/examples",
      "heading": "Replicating Plugins",
      "heading_level": 3,
      "content_markdown": "### Replicating Plugins\n\nMost applications will have state management or routing. Both of these are Vue plugins.\n\n*   cypress/support/component.js\n*   With JSX\n\n```\nimport { createPinia } from 'pinia' // or Vueximport { createI18n } from 'vue-i18n'import { mount } from 'cypress/vue'import { h } from 'vue'// We recommend that you pull this out// into a constants file that you share with// your main.js file.const i18nOptions = {  locale: 'en',  messages: {    en: {      hello: 'hello!',    },    ja: {      hello: 'こんにちは！',    },  },}Cypress.Commands.add('mount', (component, ...args) => {  args.global = args.global || {}  args.global.plugins = args.global.plugins || []  args.global.plugins.push(createPinia())  args.global.plugins.push(createI18n())  return mount(    () => {      return h(VApp, {}, component)    },    ...args  )})\n```\n\n```\nimport { createPinia } from 'pinia' // or Vueximport { createI18n } from 'vue-i18n'import { mount } from 'cypress/vue'// We recommend that you pull this out// into a constants file that you share with// your main.js file.const i18nOptions = {  locale: 'en',  messages: {    en: {      hello: 'hello!',    },    ja: {      hello: 'こんにちは！',    },  },}Cypress.Commands.add('mount', (component, ...args) => {  args.global = args.global || {}  args.global.plugins = args.global.plugins || []  args.global.plugins.push(createPinia())  args.global.plugins.push(createI18n())  // <component> is a built-in component that comes with Vue  return mount(    () => (      <VApp>        <component is={component} />      </VApp>    ),    ...args  )})\n```\n",
      "section": "app",
      "anchors": [
        "replicating-plugins"
      ],
      "path": "/llm/json/chunked/app/component-testing/vue/examples.json",
      "token_estimate": 277
    },
    {
      "id": "app/component-testing/vue/examples#replicating-the-expected-component-hierarchy",
      "doc_id": "app/component-testing/vue/examples",
      "heading": "Replicating the expected Component Hierarchy",
      "heading_level": 3,
      "content_markdown": "### Replicating the expected Component Hierarchy\n\nSome Vue applications, most famously Vue apps built on top of Vuetify, require certain components to be structured in a specific hierarchy.\n\nAll Vuetify applications require that you wrap your app in a `VApp` component when you build it. This is an implementation detail of Vuetify, but once users try to test components that depend on Vuetify, they get Vuetify-specific compilation errors and quickly find out that **they need to replicate that component hierarchy any time they need to mount a component that uses a Vuetify component**!\n\nCustom `cy.mount` commands to the rescue! You may find the JSX syntax to be more straightforward.\n\nYou'll also need to replicate the plugin setup steps from the Vuetify docs for everything to compile.\n\n*   cypress/support/component.js\n*   With JSX\n\n```\nimport Vuetify from 'vuetify/lib'import { VApp } from 'vuetify'import { mount } from 'cypress/vue'import { h } from 'vue'// We recommend that you pull this out// into a constants file that you share with// your main.js file.const vuetifyOptions = {}Cypress.Commands.add('mount', (component, ...args) => {  args.global = args.global || {}  args.global.plugins = args.global.plugins || []  args.global.plugins.push(new Vuetify(vuetifyOptions))  return mount(    () => {      return h(VApp, {}, component)    },    ...args  )})\n```\n\n```\nimport Vuetify from 'vuetify/lib'import { VApp } from 'vuetify'import { mount } from 'cypress/vue'// We recommend that you pull this out// into a constants file that you share with// your main.js file.const vuetifyOptions = {}Cypress.Commands.add('mount', (component, ...args) => {  args.global = args.global || {}  args.global.plugins = args.global.plugins || []  args.global.plugins.push(new Vuetify(vuetifyOptions))  // <component> is a built-in component that comes with Vue  return mount(    () => (      <VApp>        <component is={component} />      </VApp>    ),    ...args  )})\n```\n",
      "section": "app",
      "anchors": [
        "replicating-the-expected-component-hierarchy"
      ],
      "path": "/llm/json/chunked/app/component-testing/vue/examples.json",
      "token_estimate": 369
    },
    {
      "id": "app/component-testing/vue/examples#vue-router",
      "doc_id": "app/component-testing/vue/examples",
      "heading": "Vue Router",
      "heading_level": 3,
      "content_markdown": "### Vue Router\n\nTo use Vue Router, create a command to register the plugin and pass in a custom implementation of the router via the options param.\n\n*   cypress/support/component.js\n*   Typings\n*   Spec Usage\n\n```\nimport { mount } from 'cypress/vue'import { createMemoryHistory, createRouter } from 'vue-router'import { routes } from '../../src/router'Cypress.Commands.add('mount', (component, options = {}) => {  // Setup options object  options.global = options.global || {}  options.global.plugins = options.global.plugins || []  // create router if one is not provided  if (!options.router) {    options.router = createRouter({      routes: routes,      history: createMemoryHistory(),    })  }  // Add router plugin  options.global.plugins.push({    install(app) {      app.use(options.router)    },  })  return mount(component, options)})\n```\n\n```\nimport { mount } from 'cypress/vue'import { Router } from 'vue-router'type MountParams = Parameters<typeof mount>type OptionsParam = MountParams[1] & { router?: Router }declare global {  namespace Cypress {    interface Chainable {      /**       * Helper mount function for Vue Components       * @param component Vue Component or JSX Element to mount       * @param options Options passed to Vue Test Utils       */      mount(component: any, options?: OptionsParam): Chainable<any>    }  }}\n```\n\n```\nimport Navigation from './Navigation.vue'import { routes } from '../router'import { createMemoryHistory, createRouter } from 'vue-router'it('home link should be active when url is \"/\"', () => {  // No need to pass in custom router as default url is '/'  cy.mount(<Navigation />)  cy.get('a').contains('Home').should('have.class', 'router-link-active')})it('login link should be active when url is \"/login\"', () => {  // Create a new router instance for each test  const router = createRouter({    routes: routes,    history: createMemoryHistory(),  })  // Change location to `/login`,  // and await on the promise with cy.wrap  cy.wrap(router.push('/login'))  // Pass the already initialized router for use  cy.mount(<Navigation />, { router })  cy.get('a').contains('Login').should('have.class', 'router-link-active')})\n```\n\nCalling `router.push()` in the router for Vue 3 is an asynchronous operation. Use the [cy.wrap](/llm/markdown/api/commands/wrap.md) command to have Cypress await the promise's resolve before it continues with other commands:\n",
      "section": "app",
      "anchors": [
        "vue-router"
      ],
      "path": "/llm/json/chunked/app/component-testing/vue/examples.json",
      "token_estimate": 408
    },
    {
      "id": "app/component-testing/vue/examples#vuex",
      "doc_id": "app/component-testing/vue/examples",
      "heading": "Vuex",
      "heading_level": 3,
      "content_markdown": "### Vuex\n\nTo use a component that uses [Vuex](https://vuex.vuejs.org/), create a `mount` command that configures a Vuex store for your component.\n\n*   cypress/support/component.js\n*   Typings\n*   Spec Usage\n\n```\nimport { mount } from 'cypress/vue'import { getStore } from '../../src/plugins/store'Cypress.Commands.add('mount', (component, options = {}) => {  // Setup options object  options.global = options.global || {}  options.global.stubs = options.global.stubs || {}  options.global.stubs['transition'] = false  options.global.components = options.global.components || {}  options.global.plugins = options.global.plugins || []  // Use store passed in from options, or initialize a new one  const { store = getStore(), ...mountOptions } = options  // Add Vuex plugin  options.global.plugins.push({    install(app) {      app.use(store)    },  })  return mount(component, mountOptions)})\n```\n\nThe `getStore` method is a factory method that initializes Vuex and creates a new store. It is important that the store be initialized with each new test to ensure changes to the store don't affect other tests.\n\n```\nimport { mount } from 'cypress/vue'import { Store } from 'vuex'type MountParams = Parameters<typeof mount>type OptionsParam = MountParams[1]declare global {  namespace Cypress {    interface Chainable {      /**       * Helper mount function for Vue Components       * @param component Vue Component or JSX Element to mount       * @param options Options passed to Vue Test Utils       */      mount(        component: any,        options?: OptionsParam & { store?: Store }      ): Chainable<any>    }  }}\n```\n\n```\nimport { getStore } from '@/plugins/store'import UserProfile from './UserProfile.vue'it.only('User profile should display user name', () => {  const user = { name: 'test person' }  // getStore is a factory method that creates a new store  const store = getStore()  // mutate the store with user  store.commit('setUser', user)  cy.mount(UserProfile, {    store,  })  cy.get('div.name').should('have.text', user.name)})\n```\n",
      "section": "app",
      "anchors": [
        "vuex"
      ],
      "path": "/llm/json/chunked/app/component-testing/vue/examples.json",
      "token_estimate": 361
    },
    {
      "id": "app/component-testing/vue/examples#global-components",
      "doc_id": "app/component-testing/vue/examples",
      "heading": "Global Components",
      "heading_level": 3,
      "content_markdown": "### Global Components\n\nIf you have components that are registered globally in the main application file, set them up in your mount command so your component will render them properly:\n\n```\nimport { mount } from 'cypress/vue'import Button from '../../src/components/Button.vue'Cypress.Commands.add('mount', (component, options = {}) => {  // Setup options object  options.global = options.global || {}  options.global.components = options.global.components || {}  // Register global components  options.global.components['Button'] = Button  return mount(component, options)})\n```\n",
      "section": "app",
      "anchors": [
        "global-components"
      ],
      "path": "/llm/json/chunked/app/component-testing/vue/examples.json",
      "token_estimate": 95
    }
  ]
}