Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cypress returns webpack compilation error for .scss file in Create React App

I'm trying to add Cypress to a very basic CRA, but am running in to issues with Cypress being able to understand .scss files.

When I run npm run cypress to run the test, I receive the following error:

Error: Webpack Compilation Error
./src/App.scss 1:0
Module parse failed: Unexpected token (1:0)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
> .app {
|   align-items: center;
|   display: flex !important;
 @ ./src/App.jsx 28:0-21
 @ ./cypress/integration/App.spec.js
...

It seems like the sass-loader isn't being used when Cypress attempts to mount the component? How can I go about fixing this?

package.json:

{
  "name": "cypress_test",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "cypress": "cypress open",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "dependencies": {
    "@cypress/react": "^5.12.4",
    "@cypress/webpack-dev-server": "^1.8.4",
    "@emotion/react": "^11.9.0",
    "@emotion/styled": "^11.8.1",
    "@fontsource/roboto": "^4.5.5",
    "@mui/icons-material": "^5.6.2",
    "@mui/material": "^5.6.3",
    "@mui/styled-engine-sc": "^5.6.1",
    "@testing-library/jest-dom": "^5.16.4",
    "@testing-library/react": "^12.1.5",
    "@testing-library/user-event": "^13.5.0",
    "cypress": "^9.6.0",
    "react": "^17.0.2",
    "react-dom": "^17.0.2",
    "react-scripts": "5.0.1",
    "sass": "^1.51.0",
    "styled-components": "^5.3.5",
    "web-vitals": "^2.1.4"
  },
  "devDependencies": {
    "@babel/core": "^7.17.9",
    "@babel/preset-env": "^7.16.11",
    "@cypress/webpack-preprocessor": "^5.11.1",
    "babel-loader": "^8.2.5",
    "eslint-plugin-cypress": "^2.12.1",
    "html-webpack-plugin": "^4.5.2",
    "webpack": "^5.72.0"
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },
  "overrides": [
    {
      "extends": [
        "plugin:cypress/recommended"
      ],
      "files": [
        "cypress/**/*.js"
      ]
    }
  ],
  "resolutions": {
    "@mui/styled-engine": "npm:@mui/styled-engine-sc@latest"
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  },
  "jest": {
    "coveragePathIgnorePatterns": [
      "<rootDir>/cypress/"
    ]
  }
}

App.spec.js:

import React from 'react';
import data from '../fixtures/data.json';
import App from '../../src/App.jsx';

describe('Test search functionality', () => {
  beforeEach(() => {
    cy.mount(<App />);
  });

  it('renders new fact when search is performed', () => {
    cy.visit('http://localhost:3001')
    // Type in search input
    cy.get('input').type('Test');

    // Click on search button
    cy.get('.submit-btn').click();

    // Intercept the request and return the mock data
    cy
      .intercept({
        method: 'GET',
        url: `${process.env.REACT_APP_API_ENDPOINT}/jokes/search?query=Test`
      }, {
        fixture: data.result[1]
      })
      .as('fetchFact');

    // cy.wait(['@fetchFact']);

    cy.get('p.copy').should('contain', data.result[1].value);
  })
});

cypress/plugins/index.js:

const injectDevServer = require('@cypress/react/plugins/react-scripts');

module.exports = (on, config) => {
  injectDevServer(on, config);
  return config;
};

UPDATE: After trying the solution proposed below with modifications to the plugins/index.js file, I am receiving a new error:

Error: For the selected environment is no default script chunk format available:
JSONP Array push can be chosen when 'document' or 'importScripts' is available.
CommonJs exports can be chosen when 'require' or node builtins are available.
Make sure that your 'browserslist' includes only platforms that support these features or select an appropriate 'target' to allow selecting a chunk format by default. Alternatively specify the 'output.chunkFormat' directly.

updated /cypress/plugins/index.js:

const findWebpack = require('find-webpack')
const webpackPreprocessor = require('@cypress/webpack-preprocessor');
const injectDevServer = require('@cypress/react/plugins/react-scripts');

module.exports = (on, config) => {
  const webpackOptions = findWebpack.getWebpackOptions();

  if (!webpackOptions) {
    throw new Error('Could not find Webpack in this project');
  }

  const cleanOptions = { reactScripts: true };

  findWebpack.cleanForCypress(cleanOptions, webpackOptions);

  const options = {
    webpackOptions,
    watchOptions: {},
  };

  on('file:preprocessor', webpackPreprocessor(options));
  injectDevServer(on, config);
  return config;
};

I also removed the browserslist key from my package.json.

like image 582
J. Jackson Avatar asked May 14 '26 12:05

J. Jackson


1 Answers

Try this to add CRA webpack config to the plugins/index file of cypress:

/// <reference types="cypress" />
/// <reference types="../../../.." />
// @ts-check
const findWebpack = require('find-webpack')
const webpackPreprocessor = require('../../../..')

/**
 * @type {Cypress.PluginConfig}
 */
module.exports = (on) => {
  // find the Webpack config used by react-scripts
  const webpackOptions = findWebpack.getWebpackOptions()

  if (!webpackOptions) {
    throw new Error('Could not find Webpack in this project 😢')
  }

  // if we just pass webpackOptions to the preprocessor
  // it won't work - because react-scripts by default
  // includes plugins that split specs into chunks, etc.
  // https://github.com/cypress-io/cypress-webpack-preprocessor/issues/31

  // solution 1
  // blunt: delete entire optimization object
  // delete webpackOptions.optimization

  // solution 2
  // use a module that carefully removes only plugins
  // that we found to be breaking the bundling
  // https://github.com/bahmutov/find-webpack
  const cleanOptions = {
    reactScripts: true,
  }

  findWebpack.cleanForCypress(cleanOptions, webpackOptions)

  const options = {
    webpackOptions,
    watchOptions: {},
  }

  on('file:preprocessor', webpackPreprocessor(options))
}

Here is some links that might be useful:

Cypress Webpack Preprocessor: https://github.com/cypress-io/cypress/tree/develop/npm/webpack-preprocessor#cypress-webpack-preprocessor

how to point Cypress at Webpack configuration from react-scripts dependency: https://github.com/cypress-io/cypress/tree/develop/npm/webpack-preprocessor/examples/react-app

like image 184
Taghi Khavari Avatar answered May 16 '26 04:05

Taghi Khavari



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!