Skip to content

Instantly share code, notes, and snippets.

@textbook
Last active September 28, 2023 20:16
Show Gist options
  • Star 23 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save textbook/3377dda14efe4449772c2377188c3fa8 to your computer and use it in GitHub Desktop.
Save textbook/3377dda14efe4449772c2377188c3fa8 to your computer and use it in GitHub Desktop.
Adding Cypress to a Create React App app

Here is how to add Cypress E2E tests to a Create React App bootstrapped application. Assumes the *nix command line, you may need to adapt this for a Windows command line (or use WSL or Git Bash).

  1. Install Cypress and the Testing Library utilities for it (to match the helpers CRA installs):

    $ npm i {,@testing-library/}cypress

    i is short for install, and the braces {} are expanded by brace expansion to cypress @testing-library/cypress.

    CRA seems to install everything as a production dependency, but you can add --save-dev if you like.

  2. Open the Cypress UI to bootstrap the test setup:

    $ npx cypress open --e2e

    NPX will use the executable in the node_modules/.bin/ directory, so you can use it for things you don't want to add to the package file.

  3. Delete the example files:

    $ rm -rf ./cypress/fixtures/example.json
  4. Set a base URL in the cypress.config.js per the best practices (I've also disabled automatic video recording):

    const { defineConfig } = require("cypress");
    
    module.exports = defineConfig({
      e2e: {
        baseUrl: "http://localhost:3000",
        setupNodeEvents(on, config) {
          // implement node event listeners here
        },
      },
      video: false,
    });
  5. Set up the Testing Library utilities by adding the following to ./cypress/support/commands.js:

    import "@testing-library/cypress/add-commands";
  6. Make sure you exclude any videos and screenshots recorded by Cypress from your commits by adding the following to .gitignore:

    # Cypress
    cypress/screenshots/
    cypress/videos/
  7. Add a script that runs the E2E tests into the package file:

    "scripts": 
      "e2e": "cypress run",
      "start": "react-scripts start",
      "build": "react-scripts build",
      "test": "react-scripts test",
      "eject": "react-scripts eject"
    },
  8. Create a new test file e.g. ./cypress/e2e/home.cy.js with the following:

    it("should load the page", () => {
      cy.visit("/");
      cy.findAllByText(/learn react/i).should("have.length", 1);
    });

    This is the same as the default src/App.test.js, but running via Cypress rather than Jest.

  9. Start the app in one terminal (npm start) then run the tests in another (npm run e2e). It should pass!

  10. Install the ESLint plugin with npm install eslint-plugin-cypress then add the following to the eslintConfig object in package.json:

      "overrides": [
        { 
          "extends": [
            "plugin:cypress/recommended"
          ],
          "files": [
            "cypress/**/*.js"
          ]
        }
      ]

    This is optional, but will ensure the linting passes (by adding the Cypress globals) and give some useful hints on good test practices.

#!/bin/bash
set -euo pipefail
if [[ $# -ne 1 ]]; then
echo 'Usage: new-cra-app.sh <app-name>'
exit 1
fi
echo 'Creating default React app'
npx create-react-app@latest "$1"
cd "$1"
echo 'Installing Cypress dependencies'
npm install \
cypress \
eslint-plugin-cypress \
@testing-library/cypress
echo 'Opening Cypress, please exit the UI once it has loaded'
npx cypress open --e2e
echo 'Removing preinstalled examples'
rm -rf \
cypress/fixtures/example.json
echo 'Updating Cypress configuration'
cat <<-EOF > cypress.config.js
const { defineConfig } = require("cypress");
module.exports = defineConfig({
e2e: {
baseUrl: "http://localhost:3000",
setupNodeEvents(on, config) {
// implement node event listeners here
},
},
video: false,
});
EOF
echo "\nimport '@testing-library/cypress/add-commands';" >> cypress/support/commands.js
echo 'Creating basic E2E test'
mkdir cypress/e2e/
cat <<-EOF > cypress/e2e/home.cy.js
it("should load the page", () => {
cy.visit("/");
cy.findAllByText(/learn react/i).should("have.length", 1);
});
EOF
echo 'Ignoring Cypress test assets'
cat <<-EOF >> .gitignore
# cypress
cypress/screenshots/
cypress/videos/
EOF
echo 'Setting NPM package configuration'
npm set-script e2e 'cypress run'
npm set-script lint 'eslint cypress/ src/'
cat package.json \
| jq '.eslintConfig.overrides = [{"extends": ["plugin:cypress/recommended"], "files": ["cypress/**/*.js"]}]' \
| tee package.json
echo 'Committing changes'
git add .
git commit -m 'Set up Cypress testing'
@joseph-luketelo
Copy link

joseph-luketelo commented Oct 17, 2022

@textbook I have followed all the steps above but I could not get my e2e tests running for my react app.
When I run npm run e2e there is no output, the terminal just does not execute anything.
When I run npx cypress open --e2e the launch pad if opened but it does not load anything!
See attached screens for reference.
Thanks!
Screenshot from 2022-10-17 10-40-49
Screenshot from 2022-10-17 10-41-58

@textbook
Copy link
Author

@joseph-luketelo I couldn't recreate the issue - I just ran the new-cra-app.sh script and (apart from a slight issue with adding Cypress Testing Library, which I've just fixed) everything worked as expected. I'm using macOS not Linux, maybe it's a platform-related problem. There could also be a problem with Cypress itself, see https://docs.cypress.io/guides/references/troubleshooting#Clear-Cypress-cache.

Screenshot 2022-10-17 at 12 01 08

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment