May 9, 2024
  • All
  • Product
  • Stencil
  • stencil

Testing Stencil Components with Ease using Playwright

Stencil Team

You may have caught our recent post about testing Stencil components using WebdriverIO. We’ve also expanded support for another testing tool: Playwright! Created by Microsoft, Playwright is an automated end-to-end (e2e) testing framework built to run on all modern browser engines and operating systems. It leverages the DevTools protocol to provide reliable tests that run in actual browsers.

Let’s look at how to test Stencil components with Playwright.

Setup

If your Stencil project has an existing end-to-end testing setup via the Stencil Test Runner, learn how to sample the Playwright adapter or migrate tests over time.

Leverage the Stencil Playwright testing adapter to add Playwright to an existing Stencil project. The Stencil team built this tool to help Stencil and Playwright work better together. The best part is that you’ll write your tests using the same APIs defined and documented by Playwright.

To use Playwright, first install the Stencil Playwright adapter into an existing Stencil project, then configure Playwright, and finally, write some tests.

End-to-End Testing

For the most part, you write end-to-end Stencil tests with Playwright using the same public APIs. The Stencil Playwright adapter adds extensions that provide additional fixtures and handle nuances related to web component hydration. Be sure to import from @stencil/playwright, not @playwright/test:

import { test } from '@stencil/playwright';

Let’s explore some testing patterns.

page.goto()

The goto() method allows tests to load a predefined HTML template. This pattern is helpful for executing tests that all use the same HTML code or if additional script or style tags need to be included in the HTML. Create an HTML file that contains all the Stencil components to test:

<!-- my-component.e2e.html –>
<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf8" />

    <!-- Replace with the path to your entrypoint -->
    <script src="../../../build/test-app.esm.js" type="module"></script>
    <script src="../../../build/test-app.js" nomodule></script>
  </head>
  <body>
    <my-component first="Stencil"></my-component>
  </body>
</html>

Next, write the e2e test to verify that <my-component> writes out the name “Stencil” to the page since the “first” prop is set to “Stencil”:

import { expect } from '@playwright/test';
import { test } from '@stencil/playwright';

test.describe('my-component', () => {
  test('should render the correct name', async ({ page }) => {
    // The path here is the path to the www output relative to the dev server root directory
    await page.goto('/components/my-component/test/my-component.e2e.html');

    // Rest of test
    const component = await page.locator(‘my-component’);
    await expect(component).toHaveText(`Hello World! I’m Stencil`);
  });
});

page.setContent()

The setContent() method allows tests to define their own HTML code on a test-by-test basis. This pattern is helpful if the HTML for a test is small or to avoid affecting other tests using the page.goto() pattern and modifying a shared HTML template file.

// my-component.e2e.ts
import { expect } from '@playwright/test';
import { test } from '@stencil/playwright';

test.describe('my-component', () => {
  test('should render the correct name', async ({ page }) => {
    await page.setContent('<my-component first="Stencil"></my-component>');

    // Same assertion as the first test above
  });
});

page.waitForChanges()

The waitForChanges() method is a utility for waiting for Stencil components to rehydrate after an operation that results in a re-render:

// my-component.e2e.ts
import { expect } from '@playwright/test';
import { test } from '@stencil/playwright';

test.describe('my-component', () => {
  test('should render the correct name', async ({ page }) => {
    // Assume a template setup with the `my-component` component and a `button`
    await page.goto('/my-component/my-component.e2e.html');

    const button = page.locator('button');
    // Assume clicking the button changes the `@Prop()` values on `my-component`
    button.click();
    await page.waitForChanges();
  });
});

Write e2e Tests Today

As you can see, the above three testing patterns are straightforward to implement, even if you are new to Playwright testing. Once your tests have been written, executing them is as simple as running npx playwright test from the root of the Stencil project.

This was just a taste of what Playwright and the Stencil Playwright adapter offer. There’s much more to explore, including debugging e2e tests and screenshot/visual testing

Happy testing!


Stencil Team