Adding TestCafe to React + Typescript + Jest Project
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!