Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cypress component testing cannot import from alias #24951

Closed
sam-ghosh opened this issue Dec 2, 2022 · 6 comments
Closed

Cypress component testing cannot import from alias #24951

sam-ghosh opened this issue Dec 2, 2022 · 6 comments

Comments

@sam-ghosh
Copy link

Current behavior

We use alias imports in the application component folder, and in my component tests I need to use imports as well like this

import {InputField} from "@company/components/Input" 

But whenever I try to run cypress, it gives me this error

enter image description here

I have my folder structure like this

/project
  /cypress
    /plugins
      /index.js
    /components
      /input.component.tsx
      /input.cy.tsx
    tsconfig.json
  /src
    /components
       /input.tsx
       /button.tsx
       /form.tsx
  ...
  ...
  tsconfig.json
  tsconfig.paths.json

The tsconfig.paths.json

{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@company/*": ["./src/*"]
    }
  }
}

The tsconfig.json in the project root folder has the below configuration

{
  "extends": "./tsconfig.paths.json",
  "compilerOptions": {
    "target": "es5",
    "lib": ["dom", "dom.iterable", "esnext"],
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "noFallthroughCasesInSwitch": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "react-jsx"
  },
  "include": ["src", "cypress"],
  "exclude": []
}

The project/cypress/tsconfig.json

{
  "extends": "../tsconfig.json"
}

cypress.config.js

/* eslint-disable @typescript-eslint/no-var-requires */
import { defineConfig } from "cypress";

export default defineConfig({
  video: false,

  e2e: {
    // We've imported your old cypress plugins here.
    // You may want to clean this up later by importing these.
    setupNodeEvents(on, config) {
      return require("./cypress/plugins/index.js")(on, config);
    },
    baseUrl: "http://localhost:3000",
    experimentalSessionAndOrigin: true,
    watchForFileChanges: false,
  },

  viewportWidth: 1920,
  viewportHeight: 1080,

  component: {
    devServer: {
      framework: "create-react-app",
      bundler: "webpack",
    },
    setupNodeEvents(on, config) {
      return require("./cypress/plugins/index.js")(on, config);
    },
  },
});

cypress/plugins/index.js

const cypressTypeScriptPreprocessor = require('./cy-ts-preprocessor')

module.exports = on => {
  on('file:preprocessor', cypressTypeScriptPreprocessor)
}

And cypress/plugins/cy-ts-preprocessor.js

const wp = require("@cypress/webpack-preprocessor");
const path = require("path");
const webpackOptions = {
  resolve: {
    extensions: [".ts", ".js", ".tsx"],
    alias: {
      "@company": path.resolve(__dirname, "../../src"),
    },
  },
  module: {
    rules: [
      {
        test: /\.ts$/,
        exclude: [/node_modules/],
        use: [
          {
            loader: "ts-loader",
          },
        ],
      },
    ],
  },
};

const options = {
  webpackOptions,
};

module.exports = wp(options);

Desired behavior

The component should be mounted correctly by importing the module '@xl/containers/GenericForm'

Test code to reproduce

import React, { useState } from "react";
import { SomeComponent } from "@xl/containers/GenericForm"; // this is the offending

const ItemComponent = () => <SomeComponent />;

describe("input-field-set.cy.ts", () => {
  const mountComponent = () => {
    return cy.mount(<ItemComponent />);
  };

  it("should mount", () => {
    mountComponent();
  });
});

Cypress Version

10.1.0

Node version

v16.5.0

Operating System

macos 13.0.1 (22A400)

Debug Logs

No response

Other

No response

@lmiller1990
Copy link
Contributor

lmiller1990 commented Dec 6, 2022

I think the issue here is files served via dev-server do NOT go through the file:preprocessor - that's only used for E2E.

The problem you will run into here is that because you are using Create React App, there's not really an easy way to extend the config.

The webpack config for CRA is buried in node_modules, we get it here:

https://github.com/cypress-io/cypress/blob/develop/npm/webpack-dev-server/src/helpers/createReactAppHandler.ts#L50-L52

One option would be not using framework: 'create-react-app', but to do something like

component: {
  devServer: {
    framework: 'react',
    bundler: 'webpack',
    webpackConfig: () => {
      const defaultConfig = require('react-scripts/config/webpack.config.js')
      return { ...defaultConfig, alias: /* your alias here */ }
    }
  }
}

One other alternative would be to just eject your CRA config. The core issue is you need to modify the webpack.config to support the alias, which is currently not happening.

Alternatively (rough, private API, untested, but might work) you might be able to piggy-back off our CRA adapter. You would install @cypress/webpack-dev-server. Then...

import CRA from "@cypress/webpack-dev-server/dist/helpers/createReactAppHandler";
import { devServer }  from "@cypress/webpack-dev-server";
import { defineConfig } from "cypress";

export default defineConfig({
  component: {
    devServer: (cypressConfig) => {
      const handler = CRA.createReactAppHandler(cypressConfig);
      const webpackConfig = handler.frameworkConfig
      return devServer({
        ...cypressConfig,
        webpackConfig: {
        ...webpackConfig,
          alias: /* CUSTOM ALIAS HERE!!! */
        },
      })
    },
  },
});

Can provide more guidance if needed! Let me know if you need more ideas.

@mike-plummer
Copy link
Contributor

Unfortunately we have to close this issue due to inactivity. Please comment if there is new information to provide concerning the original issue and we can reopen.

@jainankit102
Copy link

jainankit102 commented Apr 19, 2023

I am also facing the same issue with the typescript alias.

ERROR in ./src/pages/Non-Courier/shared/services/tba.service.ts 2:0-42 Module not found: Error: Can't resolve '@Utils' in '/Users/name/Workplace/react/src/pages/Non-Courier/shared/services'

@nagash77
Copy link
Contributor

@jainankit102 If you have a reproducible example, please open a new ticket and we will be happy to investigate.

@aaron-mota
Copy link

aaron-mota commented Nov 22, 2023

I had this similar issue with aliasing with a CRA project (non-ejected) and Cypress "component" testing. I was able to solve it.


My versions:

"cypress": "^12.14.0",
"react-scripts": "5.0.1",

Solution:

  1. I followed the "Getting Started" instructions from Cypress's documentation to get started with component testing (Cypress > Component Testing > Getting Started)
  2. Then, I used the webpackConfig option within the cypress.config.ts file with the following setup to get Cypress component testing to work with my project's aliasing.

tsconfig.json (in root directory; already existed in my CRA project, just showing the alias):

{
  "compilerOptions": {
    "baseUrl": "./", // This must be specified if "paths" is set.
    "paths": {
      "~/*": ["src/*"] // This maps the alias "~" to your "src/" directory.
      },
      ...
  },
  "include": [
    "src"
  ]
}

cypress.config.ts (in root directory):


import { defineConfig } from "cypress";

export default defineConfig({
  e2e: {
    ...
  },
  component: {
    devServer: {
      framework: "create-react-app",
      bundler: "webpack",
      webpackConfig: (config) => (
        {
          ...config,
          resolve: {
            alias: {
              "~": "src",
            },
          },
        }
      ),
    },
  },
});

I hope this helps!

@igornog
Copy link

igornog commented Feb 22, 2024

It helped! Thank you @aaron-mota !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants