Writing Cypress tests in TypeScript using create-react-app v3

May 13, 2019

•

By Gleb Bahmutov

Let’s create a new application using Create React App v3 using TypeScript following the official instructions before adding Cypress end-to-end tests.

CRA application

$ npm i -g create-react-app
+ [email protected]
$ create-react-app cra-cypress --typescript
...
We suggest that you begin by typing:

  cd cra-cypress
  yarn start

Happy hacking!

Let’s check the application

$ cd cra-cypress
$ yarn start

The application opens at localhost:3000, notice the App.tsx in our project’s src directory.

Let’s scaffold Cypress tests. Here is how to do this extremely quickly

$ yarn add -D cypress
info Direct dependencies
├─ [email protected]
├─ [email protected]
└─ [email protected]

$ npx @bahmutov/cly init
npx: installed 72 in 7.967s
scaffolding new Cypress project
✅ scaffolded "cypress" folder with a single example spec
you can configure additional options in cypress.json file
see https://on.cypress.io/configuration

We just have a Cypress configuration file, cypress.json, and a cypress folder with tests, fixtures and bundling code (the plugins file).

cypress.json
cypress/
  fixtures/
  integration/
    spec.js
  plugins/
    index.js
  support/
    index.js

Cypress TS support

Great, let’s make sure we can write the test file cypress/integration/spec.js in TypeScript instead of JavaScript. To configure Cypress to transpile TS specs, I have written an utility package @bahmutov/add-typescript-to-cypress. All you need is to install it together with its peer dependency, Webpack:

$ yarn add -D @bahmutov/add-typescript-to-cypress webpack
info Direct dependencies
├─ @bahmutov/[email protected]
└─ [email protected]

Note: you might get this error when you try to start the application after installing the new modules

There might be a problem with the project dependency tree.
It is likely not a bug in Create React App, but something you need to fix locally.

The react-scripts package provided by Create React App requires a dependency:

  "babel-loader": "8.0.5"

Don't try to install it manually: your package manager does it automatically.
However, a different version of babel-loader was detected higher up in the tree:

  /Users/gleb/git/cra-cypress/node_modules/babel-loader (version: 8.0.6)

Just add SKIP_PREFLIGHT_CHECK=true to the .env file in the root directory of the application and restart the application.

Let’s change spec.js to spec.ts and write a test to see if it works. Here is our test file:

describe('CRA', () => {
  it('shows learn link', function () {
    cy.visit('http://localhost:3000')
    cy.get('.App-link').should('be.visible')
      .and('have.text', 'Learn React')
  })
})

In a modern text editor like VSCode, you should already see intelligent code completion working, for example showing help for the .and('have.text', ...) assertion.

But when we start Cypress with npx cypress open it shows an error!

The CRA v3 automatically puts a TypeScript settings file, tsconfig.json, in the root directory of the project with several compiler options, including noEmit: true.

{
  "compilerOptions": {
    "noEmit": true
  }
}

When we installed add-typescript-to-cypress it placed its own tsconfig.json in the cypress folder that extends the root tsconfig.json and includes the Cypress node_modules folder (this is what makes VSCode IntelliSense work). We can overwrite any TS options in the cypress/tsconfig.json to apply to our test files. For example we need to actually emit the transpiled code for Cypress to work:

{
  "extends": "../tsconfig.json",
  "include": [
    "../node_modules/cypress",
    "*/*.ts"
  ],
  "compilerOptions": {
    "noEmit": false
  }
}

Now the test should work (after restarting Cypress).

You can find the source code in the bahmutov/cra-cypress repository on GitHub.

See also