A comprehensive web component compiler that transforms TypeScript and JSX code into standards-compliant web components with complete development toolchain.
75
Comprehensive testing framework with unit testing, E2E testing, and screenshot testing capabilities. Stencil provides Jest integration, Puppeteer-based E2E testing, and extensive mocking utilities.
Unit testing utilities for testing components in isolation with JSDOM.
/**
* Creates a new spec page for unit testing components
* @param opts - Configuration options for the spec page
* @returns Promise resolving to SpecPage instance
*/
function newSpecPage(opts: NewSpecPageOptions): Promise<SpecPage>;
interface NewSpecPageOptions {
/** Components to register for testing */
components: any[];
/** HTML content to render */
html?: string;
/** Template function that returns HTML */
template?: () => string;
/** Include Stencil's built-in polyfills */
includeAnnotations?: boolean;
/** Support for checking HTML attribute/properties */
supportsShadowDom?: boolean;
/** Auto apply changes and trigger lifecycle methods */
autoApplyChanges?: boolean;
/** Suppress console logs during testing */
strictBuild?: boolean;
/** Cookie string to set on document */
cookie?: string;
/** Direction attribute for document */
direction?: string;
/** Language attribute for document */
language?: string;
/** User agent string */
userAgent?: string;
/** URL for the page */
url?: string;
}
interface SpecPage {
/** Document body element */
body: HTMLElement;
/** Full document */
doc: Document;
/** Root component element */
root?: HTMLElement;
/** Root component instance */
rootInstance?: any;
/** Window object */
win: Window;
/** Set HTML content and wait for changes */
setContent(html: string): Promise<void>;
/** Wait for all component changes to complete */
waitForChanges(): Promise<void>;
/** Flush all pending tasks */
flushLoadModule(): Promise<void>;
/** Flush all rendering tasks */
flushQueue(): Promise<void>;
}Usage Examples:
import { newSpecPage } from '@stencil/core/testing';
import { MyComponent } from './my-component';
describe('my-component', () => {
it('renders', async () => {
const page = await newSpecPage({
components: [MyComponent],
html: `<my-component first="Stencil" last="JS"></my-component>`,
});
expect(page.root).toEqualHtml(`
<my-component first="Stencil" last="JS">
<div>Hello, Stencil JS!</div>
</my-component>
`);
});
it('updates properties', async () => {
const page = await newSpecPage({
components: [MyComponent],
html: `<my-component first="John"></my-component>`,
});
page.root.last = 'Doe';
await page.waitForChanges();
expect(page.root).toEqualHtml(`
<my-component first="John" last="Doe">
<div>Hello, John Doe!</div>
</my-component>
`);
});
});End-to-end testing utilities using Puppeteer for real browser testing.
/**
* Creates a new E2E page for end-to-end testing
* @param opts - Configuration options for the E2E page
* @returns Promise resolving to E2EPage instance
*/
function newE2EPage(opts?: NewE2EPageOptions): Promise<E2EPage>;
interface NewE2EPageOptions {
/** Base URL for the test server */
url?: string;
/** HTML content to load */
html?: string;
/** Wait condition before proceeding */
waitUntil?: 'load' | 'domcontentloaded' | 'networkidle0' | 'networkidle2';
/** User agent string */
userAgent?: string;
/** Cookie strings to set */
cookie?: string | string[];
/** Viewport size */
viewport?: { width: number; height: number };
/** Disable JavaScript */
disableJavaScript?: boolean;
}
interface E2EPage {
/** Navigate to a URL */
goto(url: string, opts?: any): Promise<any>;
/** Set HTML content */
setContent(html: string, opts?: any): Promise<void>;
/** Wait for selector to appear */
waitForSelector(selector: string, opts?: any): Promise<E2EElement>;
/** Wait for function result */
waitForFunction(fn: Function | string, opts?: any, ...args: any[]): Promise<any>;
/** Wait for specified time */
waitFor(milliseconds: number): Promise<void>;
/** Find element by selector */
find(selector: string): Promise<E2EElement>;
/** Find all elements by selector */
findAll(selector: string): Promise<E2EElement[]>;
/** Set viewport size */
setViewport(viewport: { width: number; height: number }): Promise<void>;
/** Take screenshot */
screenshot(opts?: any): Promise<Buffer>;
/** Compare screenshot against baseline */
compareScreenshot(desc?: string, opts?: any): Promise<any>;
/** Close the page */
close(): Promise<void>;
}
interface E2EElement {
/** Click the element */
click(opts?: any): Promise<void>;
/** Focus the element */
focus(): Promise<void>;
/** Hover over the element */
hover(): Promise<void>;
/** Type text into the element */
type(text: string, opts?: any): Promise<void>;
/** Press a key */
press(key: string, opts?: any): Promise<void>;
/** Get element property */
getProperty(name: string): Promise<any>;
/** Get element attribute */
getAttribute(name: string): Promise<string>;
/** Get element text content */
textContent(): Promise<string>;
/** Get element inner text */
innerText(): Promise<string>;
/** Check if element is visible */
isVisible(): Promise<boolean>;
/** Wait for element to be visible */
waitForVisible(): Promise<void>;
/** Wait for element to be hidden */
waitForNotVisible(): Promise<void>;
}Usage Examples:
import { newE2EPage } from '@stencil/core/testing';
describe('my-component e2e', () => {
it('renders', async () => {
const page = await newE2EPage();
await page.setContent('<my-component></my-component>');
const element = await page.find('my-component');
expect(element).toHaveClass('hydrated');
});
it('handles interactions', async () => {
const page = await newE2EPage();
await page.setContent(`
<my-component first="John" last="Doe"></my-component>
`);
const button = await page.find('my-component >>> button');
await button.click();
const result = await page.find('my-component >>> .result');
expect(await result.textContent()).toBe('Button clicked!');
});
it('takes screenshots', async () => {
const page = await newE2EPage();
await page.setContent('<my-component></my-component>');
await page.compareScreenshot('my-component-default');
});
});Utilities for creating mock objects and DOM elements for testing.
/**
* Create a mock build context
* @returns Mock BuildCtx instance
*/
function mockBuildCtx(): BuildCtx;
/**
* Create a mock compiler context
* @returns Mock CompilerCtx instance
*/
function mockCompilerCtx(): CompilerCtx;
/**
* Create a mock compiler system
* @returns Mock CompilerSystem instance
*/
function mockCompilerSystem(): CompilerSystem;
/**
* Create a mock Stencil configuration
* @returns Mock Config instance
*/
function mockConfig(): Config;
/**
* Create a mock validated configuration
* @returns Mock ValidatedConfig instance
*/
function mockValidatedConfig(): ValidatedConfig;
/**
* Create a mock load config initialization
* @returns Mock LoadConfigInit instance
*/
function mockLoadConfigInit(): LoadConfigInit;
/**
* Create a mock logger
* @returns Mock Logger instance
*/
function mockLogger(): Logger;
/**
* Create a mock module
* @returns Mock module object
*/
function mockModule(): any;
/**
* Create a mock DOM document
* @returns Mock Document instance
*/
function mockDocument(): Document;
/**
* Create a mock DOM window
* @returns Mock Window instance
*/
function mockWindow(): Window;Usage Examples:
import { mockConfig, mockLogger, mockDocument } from '@stencil/core/testing';
describe('utility function', () => {
it('works with mock config', () => {
const config = mockConfig();
config.namespace = 'TestApp';
const result = processConfig(config);
expect(result.namespace).toBe('TestApp');
});
it('works with mock document', () => {
const doc = mockDocument();
const div = doc.createElement('div');
div.textContent = 'Hello';
expect(div.textContent).toBe('Hello');
});
});Mock implementation of the Fetch API for testing HTTP requests.
/**
* Mock fetch function for testing HTTP requests
* @param input - Request URL or Request object
* @param init - Request configuration options
* @returns Promise resolving to MockResponse
*/
function mockFetch(input: MockRequestInfo, init?: MockRequestInit): Promise<MockResponse>;
type MockRequestInfo = string | MockRequest;
interface MockRequestInit {
method?: string;
headers?: MockHeaders | Record<string, string>;
body?: string | FormData | URLSearchParams;
credentials?: 'omit' | 'same-origin' | 'include';
cache?: string;
redirect?: string;
referrer?: string;
integrity?: string;
}
class MockRequest {
constructor(input: MockRequestInfo, init?: MockRequestInit);
readonly method: string;
readonly url: string;
readonly headers: MockHeaders;
readonly body: string | null;
clone(): MockRequest;
text(): Promise<string>;
json(): Promise<any>;
}
class MockResponse {
constructor(body?: string, init?: MockResponseInit);
readonly status: number;
readonly statusText: string;
readonly headers: MockHeaders;
readonly ok: boolean;
readonly url: string;
clone(): MockResponse;
text(): Promise<string>;
json(): Promise<any>;
static json(object: any, init?: MockResponseInit): MockResponse;
}
interface MockResponseInit {
status?: number;
statusText?: string;
headers?: MockHeaders | Record<string, string>;
url?: string;
}
class MockHeaders {
constructor(init?: Record<string, string> | MockHeaders);
append(name: string, value: string): void;
delete(name: string): void;
get(name: string): string | null;
has(name: string): boolean;
set(name: string, value: string): void;
forEach(callback: (value: string, key: string) => void): void;
}Usage Examples:
import { mockFetch, MockResponse } from '@stencil/core/testing';
describe('API service', () => {
beforeEach(() => {
global.fetch = mockFetch;
});
it('handles successful response', async () => {
(fetch as any).mockResolvedValue(
new MockResponse(JSON.stringify({ id: 1, name: 'Test' }), {
status: 200,
headers: { 'Content-Type': 'application/json' }
})
);
const result = await apiService.getUser(1);
expect(result.name).toBe('Test');
});
it('handles error response', async () => {
(fetch as any).mockResolvedValue(
new MockResponse('Not found', { status: 404 })
);
await expect(apiService.getUser(999)).rejects.toThrow('User not found');
});
});Functions for integrating Stencil with Jest testing framework.
/**
* Get Jest Puppeteer environment factory
* @returns Jest environment factory function
*/
function getCreateJestPuppeteerEnvironment(): any;
/**
* Get Jest test runner factory
* @returns Jest test runner factory function
*/
function getCreateJestTestRunner(): any;
/**
* Get Jest preprocessor for Stencil files
* @returns Jest preprocessor configuration
*/
function getJestPreprocessor(): any;
/**
* Get Jest preset configuration for Stencil
* @returns Jest preset configuration object
*/
function getJestPreset(): any;
/**
* Get Jest setup test framework function
* @returns Jest setup function
*/
function getJestSetupTestFramework(): any;Additional utilities for test setup and execution.
/**
* Transpile TypeScript code for testing
* @param code - TypeScript source code
* @param opts - Transpilation options
* @returns Transpiled JavaScript code
*/
function transpile(code: string, opts?: any): Promise<string>;
/**
* Create testing environment
* @param opts - Testing configuration options
* @returns Testing environment instance
*/
function createTesting(opts?: any): Testing;
interface Testing {
run(opts: TestingRunOptions): Promise<boolean>;
destroy(): Promise<void>;
}
interface TestingRunOptions {
e2e?: boolean;
screenshot?: boolean;
spec?: boolean;
updateScreenshot?: boolean;
}
/**
* Set up console mocking utilities
* @returns Console mocker instance
*/
function setupConsoleMocker(): any;
/**
* Shuffle array elements for randomized testing
* @param array - Array to shuffle
* @returns Shuffled array
*/
function shuffleArray<T>(array: T[]): T[];
/**
* Event spy for testing component events
*/
interface EventSpy {
eventName: string;
firstEvent: CustomEvent;
lastEvent: CustomEvent;
events: CustomEvent[];
called: boolean;
callCount: number;
}Usage Examples:
import { createTesting, transpile } from '@stencil/core/testing';
// Create testing environment
const testing = createTesting();
// Run specific test types
await testing.run({
spec: true,
e2e: false,
screenshot: false
});
// Transpile TypeScript for testing
const jsCode = await transpile(`
const x: number = 42;
console.log(x);
`);Install with Tessl CLI
npx tessl i tessl/npm-stencil--coredocs
evals
scenario-1
scenario-2
scenario-3
scenario-4
scenario-5
scenario-6
scenario-7
scenario-8
scenario-9
scenario-10