Adding TestCafe to React + Typescript + Jest Project

Bret Merritt
5 min readAug 23, 2021

--

Overview

Recently I decided I wanted to learn more about end-to-end testing. In the interest of getting hands-on quickly, I chose to add TestCafe to one of my pre-existing projects so I had a featureful app ready to be tested. This project was already using Jest for unit and integration tests. This redundancy was intentional, as I wanted to write TestCafe tests that cover the same cases as my Jest tests for learning purposes.

Since this project already utilizes Jest as a test framework as well as Typescript, I ran into some interesting challenges. Therefore, I thought it might be useful to document how I set up my environment.

This article is written for others who are looking to get set up with TestCafe in a pre-existing React + Typescript + Jest project. This article mainly covers installation, and won’t cover some of the interesting things you can do with TestCafe. That article will come later, now that my environment is ready to go!

1. Install TestCafe

The first step is to of course install TestCafe! This needs to be done both within the project, and globally on your local environment so we can run testcafe commands in the console.

Run the following command in the terminal to install TestCafe globally:

npm i -g testcafe

Next, we’ll install TestCafe as a dependency for this project. Run the following command within your project’s directory:

npm i testcafe

Great! We’ve installed everything we need to get started.

2. Create end-to-end test file structure

This is how I am structuring this project:

./
┗ src
┗ Component
┣ Component.scss
┣ Component.tsx
Component.test.tsx
Component.e2e.tsx

I am going to follow the conventions I established previously with this project and add .e2e.tsx files in all my component directories, but you can set up your test file structure how you see fit. Another common convention is to have a test directory that includes all your test files in one location.

3. Update TestCafe configuration in .testcaferc.json

Whether you include your tests in your component directories or put them in a separate test directory, you’ll have to make some changes to your TestCafe configuration to specify that only .e2e.tsx files are run by TestCafe and not our pre-existing Jest .test.tsx files. Let’s do that now.

First, create a .testcaferc.json on the top-level of your project directory if one does not exist yet.

Inside, specify the default source for testcafe commands by writing the following JSON:

{
"src": ["./src/*/*.e2e.tsx"]
}

This glob format indicates that TestCafe will run all files with the extension .e2e.tsx in all directories withinsrc. Notice that this means it will NOT run files with the extension .test.tsx (or .spec.tsx for that matter). That’s great since those are our Jest files and we don’t want TestCafe to run those!

4. Write a simple test to get started

Alright, we are now ready to write a test to see TestCafe in action!

For this first test, I created the Header.e2e.tsx file in my src/Header directory. I chose this as my first test because it’s testing a very simple React component. Therefore, this is a good place to experiment with some basic tests.

In src/Header/Header.e2e.tsx I wrote the following:

This will instantiate a simple test that checks that an element with the ID of mains exists on the development server page.

5. Fix TestCafe/Jest type collisions

We’re almost done setting up TestCafe in this project, but there is one more oddity when working with both TestCafe and Jest within a Typescript project: type collisions! 🙃

Before I even dive into the issue, let’s follow best practices and do some red-green testing to see the error and find out what breaks.

Let’s start up our development server. In the console, run the following command:

npm start

Ok, did it work? Well if you’re following this example and you have both Jest and TestCafe packages in the project, you should get this error:

Failed to compile.TypeScript error in <PATH-TO-OUR-PROJECT>/src/Header/Header.e2e.tsx(15,6):
Property 'expect' does not exist on type 'DoneCallback'. TS2339

Uh oh, our development server failed to compile! So what’s happening here? Well both Jest and TestCafe have global declarations for the typing of the functiontest. Jest’s declaration expects a DoneCallback object as the parameter of the function, while TestCafe’s declaration types the parameter as a TestController.

As we can see from the error, when Typescript compiles the global variable for test, it ends up with the Jest declaration instead of the TestCafe declaration. This means our Jest tests still run as expected without any adjustments, but we can’t run our TestCafe tests!

Hopefully, these packages typing incompatibilities will get sorted with future package updates. But for now, we can simply add a line in our TestCafe tests that declares the type of test locally:

declare const test: TestFn;

This declares a variable of test with the type equal to that of TestFn. TestFn is the interface defined within the TestCafe package in node_modules. This is the exact same declaration that is made within the TestCafe package (that which gets overwritten by Jest).

Now src/Header/Header.e2e.tsx should look like this:

So, does it all work? Let’s find out!

6. Check compatibility

Ok, let’s run our code in all our environments and make sure everything is still working.

First, let’s start up our development server again:

npm start

The app should compile as expected and open in the browser. No more type collisions!

Next, let’s run our Jest tests again to make sure they’re still working:

npm run test

We should see any pre-existing Jest tests evaluate in our console. Great, our test typing hasn’t broken in Jest. Now, all we need to do is run TestCafe!

7. Run TestCafe tests!

To run the test, first we need to make sure our development server is running. In the console, run the following command:

npm start

Now that our server is running onlocalhost:3000, we’re ready to run testcafe!

Make sure you run the following command in a separate terminal window to ensure our development server keeps running in the original terminal window.

testcafe chrome

This will start up TestCafe in the Chrome browser and run any tests in the default source (which we set above to be any .e2e.tsx files in any directories within src).

A new Chrome browser should open and run our test using TestCafe!

Awesome, we did it! We’ve successfully added TestCafe to our React + Typescript + Jest project while maintaining all pre-existing functionality.

Conclusion

There are many reasons you might want both Jest and TestCafe in your project. Whether it’s to confidently boost test coverage, or for your own learning like in my case, these two technologies can work alongside each other within a Typescript project. However, there are a few hurdles to get over having to do with incorrect test files being run, and global typing.

Hopefully, this walkthrough can streamline your environmental setup, as well as teach a little something about the general TestCafe installation process, type collisions, and TestCafe configs.

Thanks for reading!

--

--