--- id: stencil title: Stencil --- [Stencil](https://stenciljs.com/) is a library for building reusable, scalable component libraries. You can test Stencil components directly in a real browser using WebdriverIO and its [browser runner](/docs/runner#browser-runner). ## Setup To set up WebdriverIO within your Stencil project, follow the [instructions](/docs/component-testing#set-up) in our component testing docs. Make sure to select `stencil` as preset within your runner options, e.g.: ```js // wdio.conf.js export const config = { // ... runner: ['browser', { preset: 'stencil' }], // ... } ``` :::info In case you use Stencil with a framework like React or Vue, you should keep the preset for these frameworks. ::: You can then start the tests by running: ```sh npx wdio run ./wdio.conf.ts ``` ## Writing Tests Given you have the following Stencil components: ```tsx title="./components/Component.tsx" import { Component, Prop, h } from '@stencil/core' @Component({ tag: 'my-name', shadow: true }) export class MyName { @Prop() name: string normalize(name: string): string { if (name) { return name.slice(0, 1).toUpperCase() + name.slice(1).toLowerCase() } return '' } render() { return (

Hello! My name is {this.normalize(this.name)}.

) } } ``` ### `render` In your test use the `render` method from `@wdio/browser-runner/stencil` to attach the component to the test page. To interact with the component we recommend using WebdriverIO commands as they behave closer to actual user interactions, e.g.: ```tsx title="app.test.tsx" import { expect } from '@wdio/globals' import { render } from '@wdio/browser-runner/stencil' import MyNameComponent from './components/Component.tsx' describe('Stencil Component Testing', () => { it('should render component correctly', async () => { await render({ components: [MyNameComponent], template: () => ( ) }) await expect($('.text')).toHaveText('Hello! My name is Stencil.') }) }) ``` #### Render Options The `render` method provides the following options: ##### `components` An array of components to test. Component classes can be imported into the spec file, then their reference should be added to the `component` array to be used throughout the test. __Type:__ `CustomElementConstructor[]`
__Default:__ `[]` ##### `flushQueue` If `false`, do not flush the render queue on the initial test setup. __Type:__ `boolean`
__Default:__ `true` ##### `template` The initial JSX that is used to generate the test. Use `template` when you want to initialize a component using their properties, instead of their HTML attributes. It will render the specified template (JSX) into `document.body`. __Type:__ `JSX.Template` ##### `html` The initial HTML used to generate the test. This can be useful to construct a collection of components working together, and assign HTML attributes. __Type:__ `string` ##### `language` Sets the mocked `lang` attribute on ``. __Type:__ `string` ##### `autoApplyChanges` By default, any changes to component properties and attributes must `env.waitForChanges()` to test the updates. As an option, `autoApplyChanges` continuously flushes the queue in the background. __Type:__ `boolean`
__Default:__ `false` ##### `attachStyles` By default, styles are not attached to the DOM and they are not reflected in the serialized HTML. Setting this option to `true` will include the component's styles in the serializable output. __Type:__ `boolean`
__Default:__ `false` #### Render Environment The `render` method returns an environment object that provides certain utility helpers to manage the component's environment. ##### `flushAll` After changes have been made to a component, such as an update to a property or attribute, the test page does not automatically apply the changes. To wait for, and apply the update, call `await flushAll()` __Type:__ `() => void` ##### `unmount` Removes the container element from the DOM. __Type:__ `() => void` ##### `styles` All styles defined by components. __Type:__ `Record` ##### `container` Container element in which the template is being rendered. __Type:__ `HTMLElement` ##### `$container` The container element as a WebdriverIO element. __Type:__ `WebdriverIO.Element` ##### `root` The root component of the template. __Type:__ `HTMLElement` ##### `$root` The root component as a WebdriverIO element. __Type:__ `WebdriverIO.Element` ### `waitForChanges` Helper method to wait for the component to be ready. ```ts import { render, waitForChanges } from '@wdio/browser-runner/stencil' import { MyComponent } from './component.tsx' const page = render({ components: [MyComponent], html: '' }) expect(page.root.querySelector('div')).not.toBeDefined() await waitForChanges() expect(page.root.querySelector('div')).toBeDefined() ``` ## Element Updates If you define properties or states in your Stencil component you have to manage when these changes should be applied to the component to be re-rendered. ## Examples You can find a full example of a WebdriverIO component test suite for Stencil in our [example repository](https://github.com/webdriverio/component-testing-examples/tree/main/stencil-component-starter).