Testing Web Components: A Journey from Vue2 to Vite and React

Samet Kabay
Trendyol Tech
Published in
6 min readNov 30, 2023

Our mission as the Seller Scout Team is to provide Trendyol users with the most affordable products, increase visibility for sellers by offering price suggestions, and enhance their profitability through increased sales.

We have the same problems for 4 different domains we own. We moved to acquire a more up-to-date technology stack, remove dependencies on our domains, and create independent pipelines. We’ll start with our Badge Earning domain, which will serve as a standard structure for our current and future projects. Although our article content focuses on unit tests within this entire transition, we will also talk about the gains and comparisons after the transition.

Our projects were developed with vue2, and since it was no longer supported, we were having difficulty finding the libraries we needed, or the ones we found were becoming increasingly out of date. Our pipeline times started to increase. Since we started to move away from sustainability and to get rid of slow pipelines, we created an updated React project created with Vite Builder and redeveloped our workflow here. The biggest difficulty during all these steps was that we had difficulty running unit tests because the library we used was a web component. We could not develop our unit tests because we could not create components with standard unit test renderers. But we found a method for the solution. Let’s take a closer look at this.

Transitioning to React with Vite

We work with the Trendyol Seller Center micro-frontend architecture, and adapting to it is our primary concern. In this context, we need a builder for the new project we are going to create. At this point, we decided to create a React app using Vite. You can find more information about Vite in this article.

Our main purpose in this article is to share how we solved the problems we encountered while testing a structure created with a web component as in the image above, with the standard “testing-library”. We also talked about the differences of the “vitest” library customized for Vite, which we use instead of Webpack. We focused on the points that need to be taken into consideration in order for a dom object running in the browser to work smoothly in test environments such as jsdom and happy-dom. Let’s examine how we use all of these together.

Let’s begin

npm init vite@latest vite-project -- --template react-ts

or

npm create vite

Select react
Select Typescript

After following these steps, we modify the vite.config.ts file in the root directory as follows:

You can update this config file according to the needs of your project. As seen here, we have chosen to use Baklava as our design system. Baklava is an open-source design system developed within Trendyol. The topic of our article continues to be developed with Web Components. For more information about Baklava, you can refer to our article.

Next is to create our application and test environment. We add Baklava Provider to src/App.tsx.

and we set up a similar structure for the test environment. We edit the tests/testing-library.tsx as follows:

Web Component Testing

What we aim to do here is to perform manipulations on the testing-library and obtain the testing-library functions that we will use in our tests. This helps prevent code duplication. An important point to note here is the use of shadow-dom-testing-library. We need this to be able to render Web Components in the testing environment. Since the created dom is a shadow dom, we must perform all our controls through it. Otherwise, the dom we expect to see will not be rendered properly.

Now let’s write a sample component and the tests for this component. Let’s create a component that allows us to filter with an input and a button to see different test types:

Now let’s start with a simple test. We add a test like this to make sure that our component is rendered:

The important thing to note here is that we place our component in the “act” wrapper. We need this because we need to expect loading delays occurring in the Dom. Otherwise, you may encounter an error like this.

Now let’s take things a little further and make changes to the shadow dom by using a custom event for input, which is a custom component.

Since we are working on a custom component, the methods available in the testing-library such as fireEvent.change and fireEvent.click will not be useful. Instead, we should use dispatchEvent as shown in the example and provide the custom event expected by the component as input. This way, we can trigger our events. The purpose of this test is to change the value of an input, send a click event to the button, and verify that the associated service method is called with the correct parameter and the correct number of times.

@event("bl-select") private _onBlSelect: EventDispatcher<ISelectOption<ValueType>[]>;

The event we need to use to trigger the change in the test environment in the select component should be “bl-select” as seen here.

A reminder; We must now use all our mock operations and methods from the jest library from the “vitest” library. Using vitest is faster than jest, easier to integrate into projects built with vite, and has the same functionality as jest.

Here is the result

After all these processes, we completed our tests for a project built with Web Component, which has differences compared to tests written in Native Dom or SPA. Sonar analyzes are in the images below.

To summarize, we used the react build of a design system created with a Web component in a Vite project and learned how to write its unit tests.

After all these improvements, you can see a few comparison images from the pipelines of the old and new projects:

A Journey from Vue2 to Vite and React

Contact us if you have any questions.

Thank you for reading.

We produce and share different solutions in many different areas. If you’re interested, you can take a look at other articles that may catch your attention.

Want to be a part of our growing company? We’re hiring! Check out our open positions and other media pages from the links below.

--

--