April 11, 2024
  • All
  • Tutorials
  • stencil

Testing Stencil Components with Ease using WebdriverIO

Matt Netkow

If you’re a developer building Stencil-based component libraries used by potentially dozens of apps, you must ensure that your Stencil components work the way you expect. To help verify that components work correctly, Stencil offers both unit testing and end-to-end testing capabilities. Over the past few months, the Stencil team has been working to expand the testing tools we support. First up is WebdriverIO, a browser and mobile automation test framework for Node.js that allows you to run component and end-to-end tests across all browsers.

We’re big fans of WebdriverIO because of its cross-browser support, real user interaction (i.e., close to native user-triggered interactions), web platform support, and the ability to run tests in the same environments your users use.

Here’s a brief tour of using WebdriverIO to test your Stencil components.

Unit Testing

WebdriverIO makes it easy to unit test components and app utility functions in the browser. WebdriverIO provides a helper package for rendering a component into a DOM tree, which resembles how your component is used in an actual application.

Given the following component:

// /src/components/my-component/my-component.tsx
import { Component, Prop, h } from '@stencil/core';

@Component({
  tag: 'my-component',
  styleUrl: 'my-component.css',
  shadow: true,
})
export class MyComponent {
  /**
   * The first name
   */
  @Prop() first: string;

private getName(): string {
    return (
      <span>{this.first}</span>
    );
  }

  render() {
    return <div>Hello, World! I'm {this.getName()}</div>;
  }
}

We use the `render` method to render the component in the browser and then verify it’s outputting the correct text:

// /src/components/my-component/my-component.test.tsx
import { h } from '@stencil/core';
import { $, expect } from '@wdio/globals';
import { render } from '@wdio/browser-runner/stencil';

import { MyComponent } from './my-component.js';

describe('my-component', () => {
  it('renders the component correctly', async () => {
    render({
      components: [MyComponent],
      template: () => <my-component first="Liam" />
    });

    const component = $('my-component');
    await expect(component).toHaveText(`Hello, World! I'm Liam`);
  });
});

More details on unit testing can be found here.

Mocking

WebdriverIO supports file-based module mocking and mocking of entire dependencies of your project. To create a mock, either create a file with the name of the module you would like to mock in the `__mocks__` directory or mock the file directly as part of your test:

import { mock, fn } from '@wdio/browser-runner';
import { format } from './utils/utils.ts';

// mock files within the project
mock('./utils/utils.ts', () => ({
    format: fn().mockReturnValue(42);
}));
// mock whole modules and replace functionality with what is defined in `./__mocks__/leftpad.ts`
mock('leftpad');

console.log(format()); // returns `42`

More details on mocking with WebdriverIO can be found in the Stencil docs.

Visual Testing

WebdriverIO supports visual testing capabilities (image comparisons on screens, elements, or a whole page) out of the box. To use it, you save a baseline image for a screen/element/full page locally and check it into your project. When other team members run the visual tests, the baseline image is compared against the newly generated image. If it fails, WebdriverIO points out the visual differences by setting the color of the misaligned text/region to a different color to make it clear where the differences are. If the visual changes are correct, you update the baseline image.

A sample visual test looks like this:

// src/components/my-component/my-component.test.tsx
it('looks visually perfect', async () => {
  render({
    components: [MyComponent],
    template: () => <my-component first="looking" last="'visually perfect' 👌" />
  });

  const component = $('my-component');
  await expect(component).toMatchElementSnapshot('MyComponent');
});

Complete details about visual testing can be found in the Stencil docs.

Improve your Stencil components today

WebdriverIO is a robust testing tool for automating your web and mobile applications. To get started using unit testing, mocking, or visual testing, follow the setup process or check out WebdriverIO’s Stencil documentation. In no time, you’ll have built a scalable, robust, and stable test suite.


Matt Netkow