Significant updates to our Jest Presets for SPFx projects

In this post, I'll cover the updates recently applied to our Jest presets for SPFx projects that support multiple versions of TypeScript.

By Last Updated: November 20, 2024 7 minutes read

Earlier this month, I refreshed my Jest presets for SharePoint Framework (SPFx) projects and added an improvement for developers who decide to use a different version of TypeScript from the default version set on new projects.

Info: Not familiar with Jest presets?

When you implement automated testing for SPFx projects with Jest, you have a handful of dependencies you need to install, make sure you use specific versions of these based on your SPFx project, configuration files you need to create, and apply some modifications to your project.

To simplify this, Jest has a concept of presets. These allow you to install Jest along with a preset that will configure your project for you in one simple step.

You can learn more about our presets in my initial post here: Introducing Jest Presets for SPFx Projects.

The Jest presets I’ve published as npm packages for SPFx projects cover three different scenarios:

Unfortunately I have to admit that I’ve been remiss in keeping these these presets current as SPFx has been updated throughout the last year. Part of that was addressing some organizational & deployment challenges with the project.

I finally rolled up my sleeves and addressed both of these issues.

Automated deployment of beta & new releases

The deployment issue was addressed using GitHub Actions. Now it’s super simple for me to publish beta versions and new releases to the NPMJS registry where these presets are made available using the above mentioned links.

If you’re interested in geeking out on automation, let me quickly explain what I did here.

Publishing beta versions

The first scenario I wanted to support was publishing beta versions of the packages as this is the only reliable way to test the preset. I solved this by creating a GitHub workflow, deploy-prerelease.yml, that creates a new release tagged as a beta with the @next tag on the package.

You can see how this looks using the npm info command and looking at the tags:

> npm info @voitanos/jest-preset-spfx-react16

@voitanos/[email protected] | MIT | deps: 12 | versions: 12
Jest preset configuration for SharePoint Framework projects that leverage React v16 (SPFx >=1.7.0).
https://github.com/Voitanos/jest-preset-spfx-react16

keywords: enzyme, jest, office 365, office365, react, sharepoint framework, sharepoint, spfx, test, tools

...

dist-tags:
latest: 1.5.0             ts3.3: 1.4.0              ts3.6: 1.4.0              ts3.9: 1.5.0
next: 1.5.0-beta.86af7e8  ts3.4: 1.4.0              ts3.7: 1.4.0
ts2.9: 1.3.2              ts3.5: 1.4.0              ts3.8: 1.5.0

From the above command and output, you can see the following from the dist-tags section of the output:

  • The currently published version is v1.5.0, is indicated by the latest tag.
  • The beta version is v1.5.0-beta.86af7e8, is indicated by the next tag. This is only used when checking the npm package before release. In fact, the version this points to matches the same codebase of the published version.

Feel free to take a look how I implemented this by checking out the workflow from the link above.

Did you notice all those other tags from the output above? That’s the other huge improvement to these presets.

Publishing production versions

The next task was to automate the process of publishing new production versions of the preset npm package to the NPMJS registry. I did this using two workflows.

First, when a new tag is pushed to the repo, the workflow draft-release.yml creates a new release but only in draft form. This isn’t necessary, but it just automated one step.

Then, when I’m ready to publish to npm, the workflow deploy-release.yml is fired when a release is published to the repo. So, when I open the draft release created in the previous workflow and publish it, that triggers this workflow to publish the current package to the NPMJS registry.

These three workflows greatly improve the development and publishing cycle which should make it easy to keep them updated with new versions of the SharePoint Framework and TypeScript.

Support for multiple versions of TypeScript

One of the biggest challenges when testing SPFx projects with Jest is the matrix of all the dependency packages and the associated versions you need for your project. There are three main vectors that you could take account for in your testing dependencies, which are:

  • Version of the SharePoint Framework your project relies on
  • Version of React used by the project
  • Version of TypeScript used to transpile the project

Thankfully we can simplify this matrix down to a single vector.

We don’t need to worry about the version of SPFx the project is using because you aren’t testing the SharePoint Framework; you’re only testing your code. While it your code will use the SPFx API, you shouldn’t be testing it… that’s not your system under test.

We can also ignore the version of React. I’m accounting for that by publishing a different preset that applies to the version of React you’re using your project (React v15 & React v16). Not using React at all? There’s a preset for that too!

That leaves us with TypeScript. The choice of the TypeScript version that you use in your SPFx project is the single biggest determining factor for all dependencies you include in your project. This is especially true with Jest!

Jest & TypeScript

Jest doesn’t natively understand TypeScript, the language we use in SPFx project. Jest only understands JavaScript. However, you can add the transformer ts-jest that will transpile your TypeScript to JavaScript on the fly when you test it.

And then there’s the type declarations for Jest, published under the @types/jest package.

The version of Jest isn’t important, except that ts-jest & @types/jest only work with a specific combination of Jest and TypeScript versions.

So, we have to work backwards… the version of TypeScript you use in your SPFx project dictates the version of ts-jest you can use (based on what that project supports), which dictates the version of Jest you can use which dictates the version of @types/jest you can use.

SPFx projects are configured with a default version of TypeScript. You can review the default version of TypeScript with each version of SPFx from the SPFx docs: SharePoint Framework development tools & libraries compatibility - SPFx development environment compatibility.

For example, the current version fo SPFx is v1.12.1 and it defaults to TypeScript v3.7.x. But, as I show you in my post The relationship between the SPFx development toolchain & TypeScript, you can use TypeScript v3.8 or v3.9 in your project with a little extra work.

But if you do that, it changes the testing dependencies. For instance, by upgrading your version of TypeScript to v3.8 or v3.9, you will have to use ts-jest v26 (while TypeScript v3.3 was only supported by ts-jest v25) but that also means you can use Jest v26 instead of the older v25!

But I don’t have time to figure all that out!

I know… neither do I on a day-to-day basis! That’s why I created these presets… and those little tags you saw in the output when you ran the npm info command!

> npm info @voitanos/jest-preset-spfx-react16

@voitanos/[email protected] | MIT | deps: 12 | versions: 12
Jest preset configuration for SharePoint Framework projects that leverage React v16 (SPFx >=1.7.0).
https://github.com/Voitanos/jest-preset-spfx-react16

keywords: enzyme, jest, office 365, office365, react, sharepoint framework, sharepoint, spfx, test, tools

...

dist-tags:
latest: 1.5.0             ts3.3: 1.4.0              ts3.6: 1.4.0              ts3.9: 1.5.0
next: 1.5.0-beta.86af7e8  ts3.4: 1.4.0              ts3.7: 1.4.0
ts2.9: 1.3.2              ts3.5: 1.4.0              ts3.8: 1.5.0

Now those other tags like ts3.7, ts3.8, & all the others might make a bit more sense. Let’s say you’ve created a brand new SPFx v1.12.1 React project. That means you’re using TypeScript v3.7 which you can see by looking at the @microsoft/rush-stack-compiler-#.# reference in your project’s package.json file.

{
  "name": "cswp-apollo-viewer-react",
  ..
  "dependencies": {
    "@microsoft/sp-core-library": "1.12.1",
    ..
    "react": "16.9.0",
    "react-dom": "16.9.0"
  },
  "devDependencies": {
    "@microsoft/rush-stack-compiler-3.7": "0.6.37",
    "@microsoft/sp-build-web": "1.12.1",
    ..
  }
}

All you have to do to use the testing preset I created is install the matching tagged version. In this case, install the ts3.7 tag, which points to v1.4.0 of our @voitanos/jest-preset-spfx-react16 package:

npm install @voitanos/[email protected] --save-dev --save-exact

But if you upgraded you project to TypeScript v3.8, you’d use that tagged version, which points to v1.5.0 of the same package that supports TypeScript v3.8:

npm install @voitanos/[email protected] --save-dev --save-exact

Confused? Don’t be… these instructions are all found in the README of each preset, as well as the homepage of the package in the NPMJS registry.