CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-vue--test-utils

Vue.js testing utilities for Vue 3 applications providing component mounting, wrapper classes, and test utilities

Pending
Overview
Eval results
Files

utilities.mddocs/

Testing Utilities

Helper functions and utilities for common testing scenarios, including promise resolution, component lifecycle management, server-side rendering, and error handling.

Capabilities

Promise Resolution

Utility for flushing all pending promises in the microtask queue, essential for testing async operations.

/**
 * Flush all pending promises in the microtask queue
 * Ensures all async operations complete before continuing test execution
 * @returns Promise that resolves after all pending promises are flushed
 */
function flushPromises(): Promise<void>;

Usage Examples:

import { mount, flushPromises } from "@vue/test-utils";

test('async operation handling', async () => {
  const wrapper = mount(AsyncComponent);
  
  // Trigger async operation
  await wrapper.find('button').trigger('click');
  
  // Wait for all promises to resolve
  await flushPromises();
  
  // Now safe to make assertions on async results
  expect(wrapper.text()).toContain('Async data loaded');
});

test('API call with delay', async () => {
  const wrapper = mount(ApiComponent);
  
  // Component makes API call on mount
  await flushPromises();
  
  // API response should now be processed
  expect(wrapper.find('.loading').exists()).toBe(false);
  expect(wrapper.find('.data').exists()).toBe(true);
});

Automatic Component Cleanup

Utilities for automatically unmounting components after tests to prevent memory leaks and test interference.

/**
 * Enable automatic unmounting of components after each test
 * Integrates with test framework hooks to ensure cleanup
 * @param hook - Test framework hook function (e.g., afterEach)
 */
function enableAutoUnmount(hook: (callback: () => void) => void): void;

/**
 * Disable automatic unmounting and clear tracked instances
 * Useful when you need manual control over component lifecycle
 */
function disableAutoUnmount(): void;

Usage Examples:

import { enableAutoUnmount, disableAutoUnmount } from "@vue/test-utils";

// Jest integration
enableAutoUnmount(afterEach);

// Vitest integration
import { afterEach } from 'vitest';
enableAutoUnmount(afterEach);

// Mocha integration
enableAutoUnmount(afterEach);

// Manual control
describe('manual cleanup tests', () => {
  beforeAll(() => {
    disableAutoUnmount();
  });
  
  afterEach(() => {
    // Manual cleanup when needed
    wrapper?.unmount();
  });
});

Server-Side Rendering

Utility for testing Vue components in server-side rendering contexts.

/**
 * Render a Vue component to HTML string for SSR testing
 * Uses Vue's server renderer without DOM attachment
 * @param component - Vue component to render
 * @param options - Mounting options (attachTo not supported)
 * @returns Promise resolving to HTML string
 */
function renderToString<T>(
  component: T,
  options?: SSRMountingOptions<T>
): Promise<string>;

interface SSRMountingOptions<T> {
  /** Component props */
  props?: ComponentProps<T>;
  /** Component slots */
  slots?: Record<string, any>;
  /** Global configuration */
  global?: GlobalMountOptions;
  /** Component attributes */
  attrs?: Record<string, unknown>;
  /** Component data override */
  data?(): Record<string, unknown>;
  // Note: attachTo is not supported in SSR
}

Usage Examples:

import { renderToString } from "@vue/test-utils";

test('SSR rendering', async () => {
  const html = await renderToString(MyComponent, {
    props: {
      title: "SSR Test",
      items: ["item1", "item2"]
    },
    slots: {
      default: "Slot content"
    }
  });
  
  expect(html).toContain("SSR Test");
  expect(html).toContain("item1");
  expect(html).toContain("Slot content");
  expect(html).not.toContain("data-v-"); // No scoped CSS in SSR
});

test('SSR with global config', async () => {
  const html = await renderToString(MyComponent, {
    global: {
      provide: {
        theme: 'dark'
      },
      components: {
        'GlobalComponent': StubComponent
      }
    }
  });
  
  expect(html).toContain('theme-dark');
});

Error Wrapper Creation

Utility for creating error wrapper proxies that provide better error messages for failed element queries.

/**
 * Create error wrapper proxy for failed find operations
 * Provides helpful error messages and supports method chaining
 * @param selector - The selector that failed to match
 * @returns Proxy that throws on method calls except exists()
 */
function createWrapperError(selector: string): WrapperLike;

interface WrapperLike {
  /** Returns false for error wrappers */
  exists(): boolean;
  /** Throws error for any other method calls */
  [key: string]: any;
}

Usage Examples:

import { mount } from "@vue/test-utils";

test('error wrapper behavior', () => {
  const wrapper = mount(MyComponent);
  
  // This creates an error wrapper since selector doesn't exist
  const errorWrapper = wrapper.find('.non-existent');
  
  // exists() returns false without throwing
  expect(errorWrapper.exists()).toBe(false);
  
  // Other methods throw helpful errors
  expect(() => errorWrapper.text()).toThrow(
    'Cannot call text on an empty wrapper'
  );
  
  expect(() => errorWrapper.trigger('click')).toThrow(
    'Cannot call trigger on an empty wrapper'
  );
});

// Practical usage with conditional logic
test('conditional element testing', () => {
  const wrapper = mount(MyComponent);
  const optionalElement = wrapper.find('.optional-element');
  
  if (optionalElement.exists()) {
    expect(optionalElement.text()).toBe('Optional content');
  }
});

RouterLink Stub Component

Pre-built stub component for Vue Router's RouterLink to simplify router testing.

/**
 * Stub component for Vue Router's RouterLink
 * Provides mock router functionality for testing without requiring actual router
 * Renders as anchor tag by default, supports custom rendering with custom prop
 */
const RouterLinkStub: Component & {
  props: {
    /** Router link destination (route path or route object) */
    to: string | RouteLocationRaw;
    /** Enable custom rendering (renders slot content without wrapper) */
    custom?: boolean;
  };
  /** Mock router link composable values */
  setup(): {
    /** Mock route object */
    route: RouteLocationNormalizedLoaded;
    /** Mock href value */
    href: string;
    /** Mock active state */
    isActive: boolean;
    /** Mock exact active state */
    isExactActive: boolean;
    /** Mock navigation function */
    navigate: (e?: MouseEvent) => void;
  };
};

Usage Examples:

import { mount, RouterLinkStub } from "@vue/test-utils";

test('router link interaction', async () => {
  const wrapper = mount(MyComponent, {
    global: {
      stubs: {
        'router-link': RouterLinkStub
      }
    }
  });
  
  const routerLink = wrapper.findComponent(RouterLinkStub);
  expect(routerLink.props('to')).toBe('/target-route');
  
  // RouterLinkStub provides mock router functionality
  await routerLink.trigger('click');
  expect(routerLink.emitted('navigate')).toHaveLength(1);
});

// Global stub configuration
import { config, RouterLinkStub } from "@vue/test-utils";

config.global.stubs = {
  'router-link': RouterLinkStub
};

Integration Patterns

Common patterns for integrating utilities with different testing frameworks.

Jest Integration

import { enableAutoUnmount, flushPromises } from "@vue/test-utils";

// Global setup
enableAutoUnmount(afterEach);

// In tests
beforeEach(async () => {
  // Ensure clean state
  await flushPromises();
});

Vitest Integration

import { enableAutoUnmount, flushPromises } from "@vue/test-utils";
import { afterEach, beforeEach } from 'vitest';

enableAutoUnmount(afterEach);

beforeEach(async () => {
  await flushPromises();
});

Custom Test Helpers

import { mount, flushPromises } from "@vue/test-utils";

// Custom helper combining mounting and promise flushing
export async function mountAndFlush(component, options = {}) {
  const wrapper = mount(component, options);
  await flushPromises();
  return wrapper;
}

// Custom helper for SSR testing
export async function renderAndTest(component, options = {}) {
  const html = await renderToString(component, options);
  return {
    html,
    contains: (text) => html.includes(text),
    hasClass: (className) => html.includes(`class="${className}"`),
    hasAttribute: (attr, value) => html.includes(`${attr}="${value}"`)
  };
}

Error Handling

Utility functions handle errors in these scenarios:

  • flushPromises: Rarely throws, but may propagate unhandled promise rejections
  • enableAutoUnmount: Throws if hook function is invalid
  • renderToString: Throws if component rendering fails or options are invalid
  • createWrapperError: Creates proxies that throw descriptive errors on method calls
import { flushPromises, renderToString } from "@vue/test-utils";

try {
  await flushPromises();
} catch (error) {
  // Handle any unhandled promise rejections
  console.error('Promise flush error:', error);
}

try {
  const html = await renderToString(BrokenComponent);
} catch (error) {
  console.error('SSR render error:', error.message);
}

Install with Tessl CLI

npx tessl i tessl/npm-vue--test-utils

docs

configuration.md

dom-wrapper.md

index.md

mounting.md

utilities.md

vue-wrapper.md

tile.json