or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/npm-cypress--vue

Browser-based Component Testing for Vue.js with Cypress.io ✌️🌲

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/@cypress/vue@5.0.x

To install, run

npx @tessl/cli install tessl/npm-cypress--vue@5.0.0

index.mddocs/

Cypress Vue Component Testing

@cypress/vue is a Vue.js component testing library that enables browser-based component testing for Vue 3 applications within the Cypress testing framework. It provides a mount utility that allows developers to mount Vue components directly in Cypress tests with full access to Vue's reactive system, component lifecycle, and ecosystem features including Vue Router, Vuex, and i18n.

Note: This package is bundled with the cypress package and should not need to be installed separately. Installing and importing mount from @cypress/vue should only be done for advanced use-cases.

Package Information

  • Package Name: @cypress/vue
  • Package Type: npm
  • Language: TypeScript
  • Installation: Included with Cypress (advanced use-cases: npm install @cypress/vue)

Core Imports

import { mount } from "@cypress/vue";

For Vue Test Utils access:

import { mount, VueTestUtils } from "@cypress/vue";

Basic Usage

import { mount } from "@cypress/vue";
import MyComponent from "./MyComponent.vue";

describe("MyComponent", () => {
  it("renders correctly", () => {
    mount(MyComponent, { 
      props: { message: "Hello World" } 
    });
    
    cy.get('[data-testid="message"]').should("contain", "Hello World");
  });
});

Architecture

@cypress/vue is built around several key components:

  • Mount Function: Core utility for mounting Vue components in Cypress tests with comprehensive TypeScript support
  • Vue Test Utils Integration: Re-exports Vue Test Utils while wrapping the mount function with Cypress-specific behavior
  • Global Extensions: Extends Cypress global object with Vue-specific properties for component access
  • Type System: Full TypeScript integration with multiple overloads supporting all Vue 3 component patterns
  • Lifecycle Management: Automatic cleanup between tests and hook integration

Capabilities

Component Mounting

The primary capability for mounting Vue components in Cypress tests with full type safety and Vue ecosystem support.

/**
 * Mounts a Vue component and returns a Cypress chainable containing the wrapper and component
 * @param componentOptions - Vue component to mount
 * @param options - Mounting options including props, global configuration, etc.
 * @returns Cypress chainable with wrapper and component access
 */
function mount<T>(
  componentOptions: T,
  options?: CyMountOptions<any>
): Cypress.Chainable<{
  wrapper: VueWrapper<ComponentPublicInstance>;
  component: ComponentPublicInstance;
}>;

Vue Test Utils Integration

Access to Vue Test Utils functionality with Cypress-specific modifications.

/**
 * Vue Test Utils re-exports with mount and shallowMount excluded
 * Provides utilities like config, flushPromises, enableAutoUnmount, etc.
 */
const VueTestUtils: {
  config: GlobalConfigOptions;
  flushPromises(): Promise<void>;
  enableAutoUnmount(hook: Function): void;
  disableAutoUnmount(): void;
  createWrapperError(message: string): Error;
  [key: string]: any;
};

Global Component Access

Access mounted components through Cypress global properties.

/**
 * Global Cypress extensions for Vue components
 */
declare global {
  namespace Cypress {
    interface Cypress {
      /** VueWrapper instance for the currently mounted component */
      vueWrapper: VueWrapper<ComponentPublicInstance>;
      /** Vue component instance (VM) for direct access */
      vue: ComponentPublicInstance;
    }
  }
}

Mount Callback (Deprecated)

Helper function for mounting components in test hooks. Removed as of Cypress 11.0.0.

/**
 * @deprecated Removed as of Cypress 11.0.0. Use mount() directly in tests instead.
 * Helper function for mounting a component quickly in test hooks.
 * @param component - Vue component to mount
 * @param options - Mounting options
 * @returns Function that throws error when called
 */
function mountCallback(
  component: any,
  options?: CyMountOptions<any>
): () => void;

Types

Mounting Options

interface CyMountOptions<Props, Data = {}> {
  /** Component props */
  props?: Props;
  /** Global configuration (plugins, components, etc.) */
  global?: {
    plugins?: Array<Plugin>;
    components?: Record<string, Component>;
    directives?: Record<string, Directive>;
    mixins?: Array<ComponentOptionsMixin>;
    mocks?: Record<string, any>;
    provide?: Record<string | symbol, any>;
    config?: Partial<AppConfig>;
  };
  /** Slots for the component */
  slots?: Record<string, any>;
  /** Attributes to apply to component */
  attrs?: Record<string, any>;
  /** Data for the component */
  data?: () => Data;
  /** Whether to log mount in Cypress command log (default: true) */
  log?: boolean;
  /** @deprecated Use global instead */
  extensions?: {
    use?: Array<Plugin>;
    mixin?: Array<ComponentOptionsMixin>;
    plugins?: Array<Plugin>;
    mixins?: Array<ComponentOptionsMixin>;
  };
}

Component Types

/**
 * Vue component wrapper providing testing utilities
 */
interface VueWrapper<T extends ComponentPublicInstance> {
  /** Component instance */
  vm: T;
  /** Set component props */
  setProps(props: Record<string, any>): Promise<void>;
  /** Set component data */
  setData(data: Record<string, any>): Promise<void>;
  /** Trigger a DOM event */
  trigger(event: string, options?: Record<string, any>): Promise<void>;
  /** Find elements by selector */
  find(selector: string): DOMWrapper<Element>;
  /** Find all elements by selector */
  findAll(selector: string): DOMWrapper<Element>[];
  /** Get component HTML */
  html(): string;
  /** Get component text */
  text(): string;
  /** Check if wrapper exists */
  exists(): boolean;
  /** Unmount the component */
  unmount(): void;
}

/**
 * Vue 3 component public instance
 */
interface ComponentPublicInstance {
  /** Component props */
  $props: Record<string, any>;
  /** Component data */
  $data: Record<string, any>;
  /** Component methods */
  [key: string]: any;
  /** Emit custom events */
  $emit(event: string, ...args: any[]): void;
  /** Access parent component */
  $parent: ComponentPublicInstance | null;
  /** Access root component */
  $root: ComponentPublicInstance;
  /** Component lifecycle hooks */
  $nextTick(fn?: () => void): Promise<void>;
}

/**
 * Vue plugin interface
 */
interface Plugin {
  install(app: any, ...options: any[]): void;
}

/**
 * Vue component type
 */
type Component = any;

/**
 * Vue directive interface
 */
interface Directive {
  beforeMount?(el: Element, binding: any): void;
  mounted?(el: Element, binding: any): void;
  beforeUpdate?(el: Element, binding: any): void;
  updated?(el: Element, binding: any): void;
  beforeUnmount?(el: Element, binding: any): void;
  unmounted?(el: Element, binding: any): void;
}

/**
 * Vue component options mixin
 */
type ComponentOptionsMixin = Record<string, any>;

/**
 * Vue app configuration
 */
interface AppConfig {
  errorHandler?: (err: any, vm: any, info: string) => void;
  warnHandler?: (msg: string, vm: any, trace: string) => void;
  globalProperties?: Record<string, any>;
  performance?: boolean;
}

/**
 * DOM wrapper for testing utilities
 */
interface DOMWrapper<ElementType extends Element> {
  element: ElementType;
  text(): string;
  html(): string;
  exists(): boolean;
  trigger(event: string, options?: Record<string, any>): Promise<void>;
  setValue(value: any): Promise<void>;
}

/**
 * Vue Test Utils global configuration options
 */
interface GlobalConfigOptions {
  global?: {
    plugins?: Array<Plugin>;
    components?: Record<string, Component>;
    directives?: Record<string, Directive>;
    mixins?: Array<ComponentOptionsMixin>;
  };
}

Usage Examples

Basic Component Mounting

import { mount } from "@cypress/vue";
import Counter from "./Counter.vue";

it("increments counter", () => {
  mount(Counter, {
    props: { initialValue: 5 }
  });
  
  cy.get('[data-testid="count"]').should("contain", "5");
  cy.get('[data-testid="increment"]').click();
  cy.get('[data-testid="count"]').should("contain", "6");
});

Mounting with Global Configuration

import { mount } from "@cypress/vue";
import router from "./router";
import store from "./store";
import MyPage from "./MyPage.vue";

it("renders page with router and store", () => {
  mount(MyPage, {
    global: {
      plugins: [router, store],
      components: {
        CustomButton: ButtonComponent
      }
    }
  });
  
  cy.get('[data-testid="page-title"]').should("be.visible");
});

Accessing Component Instance

import { mount } from "@cypress/vue";
import FormComponent from "./FormComponent.vue";

it("validates form programmatically", () => {
  mount(FormComponent);
  
  // Access component through global Cypress object
  cy.then(() => {
    Cypress.vue.validateForm();
    expect(Cypress.vue.isValid).to.be.false;
  });
});

Using Vue Test Utils with Component

import { mount } from "@cypress/vue";
import AsyncComponent from "./AsyncComponent.vue";

it("handles async operations", () => {
  mount(AsyncComponent);
  
  cy.get('[data-testid="load-button"]').click();
  
  // Use Vue Test Utils for async handling
  cy.then(async () => {
    await Cypress.vueWrapper.vm.$nextTick();
    // Component state updated
  });
});

Functional Component Mounting

import { mount } from "@cypress/vue";
import { h } from "vue";

it("mounts functional component", () => {
  mount(() => h("div", { "data-testid": "functional" }, "Hello"));
  
  cy.get('[data-testid="functional"]').should("contain", "Hello");
});

Component with Slots

import { mount } from "@cypress/vue";
import CardComponent from "./CardComponent.vue";

it("renders component with slots", () => {
  mount(CardComponent, {
    slots: {
      header: '<h2 data-testid="header">Card Title</h2>',
      default: '<p data-testid="content">Card content</p>',
      footer: '<button data-testid="action">Action</button>'
    }
  });
  
  cy.get('[data-testid="header"]').should("contain", "Card Title");
  cy.get('[data-testid="content"]').should("contain", "Card content");
  cy.get('[data-testid="action"]').should("be.visible");
});

Component with Provide/Inject

import { mount } from "@cypress/vue";
import ChildComponent from "./ChildComponent.vue";

it("provides context to component", () => {
  mount(ChildComponent, {
    global: {
      provide: {
        theme: "dark",
        api: mockApiService
      }
    }
  });
  
  cy.get('[data-testid="themed-element"]').should("have.class", "dark-theme");
});

Error Handling

@cypress/vue includes built-in error handling for common issues:

  • Invalid component options: Throws descriptive errors for malformed components
  • Missing dependencies: Clear messages when Vue or required peer dependencies are missing
  • Mount failures: Detailed error reporting when component mounting fails
  • Wrapper access errors: Helpful guidance when trying to access wrapper methods incorrectly

Common error scenarios:

// This will throw a helpful error
cy.mount(MyComponent).find('.selector'); // Wrong - can't chain VTU methods

// Correct approach
cy.mount(MyComponent).then(({ wrapper }) => {
  wrapper.find('.selector');
});

Migration Notes

For users migrating from older versions:

  • mountCallback function is deprecated as of Cypress 11.0.0
  • The extensions option is deprecated in favor of global
  • Vue 2 support was removed - Vue 3+ is required
  • TypeScript types have been significantly improved for better development experience