admin管理员组

文章数量:1291128

I have a React monorepo built using vite and npm workspaces structured as below

myapp
  - packages
     - app1
       - src
         ...
       package.json
     - app2
       - src
         ...
       package.json
     - app3
       - src
         ...
       package.json
  - cypress
    - support
      e2e.js
  package.json
  cypress.config.js


myapp/package.json

{
  "name": "myapp",
  "type": "module",
  "scripts": {
     "preview:watch": "npm run preview --workspaces --if-present"
     "e2e:open": "concurrently --kill-others \"npm run preview:watch\" \"cypress open --e2e --browser chrome\"",
     "e2e:headless": "cypress run --e2e --headless",
     "e2e:coverage": "nyc report --reporter=text --reporter=text-summary --reporter=lcov"
  },
  "nyc": {
    "report-dir": "cypress-coverage"
  },
  "dependencies": {
     "react": "^18.2.0",
     "react-dom": "^18.2.0",
  },
  "devDependencies": {
      "@cypress/code-coverage": "^3.12.44",
      "vite": "^5.0.8",
      "vite-plugin-istanbul": "^6.0.2"
  },
  "workspaces": [
    "packages/app1",
    "packages/app2",
    "packages/app3"
  ]
}

cypress.config.js

import { defineConfig } from "cypress";
import coverage from "@cypress/code-coverage/task.js";

export default defineConfig({
  e2e: {
    baseUrl: "http://localhost:3000/",
    setupNodeEvents(on, config) {
      on("task", {
        log(message) {
          console.info(message);
          return null;
        },
      });
      coverage(on, config);
      return config;
    },
  },
});

cypress/support/e2e.js

import '@cypress/code-coverage/support'
...

vite.config.js

import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import istanbul from "vite-plugin-istanbul";

export default ({ mode }, packagePath, chunks) => {
  return defineConfig({
    define: {
      "process.env": JSON.stringify(process.env),
    },
    plugins: [
      react(),
      istanbul({
        include: "**",
        forceBuildInstrument: true,
        cwd: "../.."
      }),
    ],
    esbuild: {
      loader: "jsx",
    },
    build: {
      lib: {
        entry: resolve(__dirname, `${packagePath}/src/App.jsx`),
        name: "myapp",
        fileName: "index",
        formats: ["es"],
      },
      rollupOptions: {
        output: {
          entryFileNames: "index.js",
          assetFileNames: "index.css",
          manualChunks: chunks,
        },
      },
    },
    preview: {
      port: 3000,
      open: "http://localhost:8080/landing.html",
    },
    resolve: {
      alias: {
        "@parent": path.resolve(__dirname, "."),
        "@app1": path.resolve(__dirname, "./packages/app1"),
        "@app2": path.resolve(__dirname, "./packages/app2"),
        "@app3": path.resolve(__dirname, "./packages/app3")
      },
    },
  });
};

To collect cypress code coverage, I am instrumenting code during the build stage (before running e2e tests) using npm run preview which happens with the help of vite-plugin-istanbul. When I run e2e tests using npm run e2e:open I can see the instrumented code in window.__coverage__ in Test iframe but it isn't picked up by cypress-coverage.

⚠️ file /Users/abc/projects/myapp/.nyc_output/out.json has no coverage information
[1] Did you fet to instrument your web application? Read 
[1]   code-coverage ⚠️ file /Users/abc/projects/myapp/.nyc_output/out.json has no coverage information +18s

When I run npm run preview, the cwd is packages/app1. As I want to collect coverage for all src files in all packages, I have given cwd:"../.." in vite.config.js but still no luck.

I have a React monorepo built using vite and npm workspaces structured as below

myapp
  - packages
     - app1
       - src
         ...
       package.json
     - app2
       - src
         ...
       package.json
     - app3
       - src
         ...
       package.json
  - cypress
    - support
      e2e.js
  package.json
  cypress.config.js


myapp/package.json

{
  "name": "myapp",
  "type": "module",
  "scripts": {
     "preview:watch": "npm run preview --workspaces --if-present"
     "e2e:open": "concurrently --kill-others \"npm run preview:watch\" \"cypress open --e2e --browser chrome\"",
     "e2e:headless": "cypress run --e2e --headless",
     "e2e:coverage": "nyc report --reporter=text --reporter=text-summary --reporter=lcov"
  },
  "nyc": {
    "report-dir": "cypress-coverage"
  },
  "dependencies": {
     "react": "^18.2.0",
     "react-dom": "^18.2.0",
  },
  "devDependencies": {
      "@cypress/code-coverage": "^3.12.44",
      "vite": "^5.0.8",
      "vite-plugin-istanbul": "^6.0.2"
  },
  "workspaces": [
    "packages/app1",
    "packages/app2",
    "packages/app3"
  ]
}

cypress.config.js

import { defineConfig } from "cypress";
import coverage from "@cypress/code-coverage/task.js";

export default defineConfig({
  e2e: {
    baseUrl: "http://localhost:3000/",
    setupNodeEvents(on, config) {
      on("task", {
        log(message) {
          console.info(message);
          return null;
        },
      });
      coverage(on, config);
      return config;
    },
  },
});

cypress/support/e2e.js

import '@cypress/code-coverage/support'
...

vite.config.js

import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import istanbul from "vite-plugin-istanbul";

export default ({ mode }, packagePath, chunks) => {
  return defineConfig({
    define: {
      "process.env": JSON.stringify(process.env),
    },
    plugins: [
      react(),
      istanbul({
        include: "**",
        forceBuildInstrument: true,
        cwd: "../.."
      }),
    ],
    esbuild: {
      loader: "jsx",
    },
    build: {
      lib: {
        entry: resolve(__dirname, `${packagePath}/src/App.jsx`),
        name: "myapp",
        fileName: "index",
        formats: ["es"],
      },
      rollupOptions: {
        output: {
          entryFileNames: "index.js",
          assetFileNames: "index.css",
          manualChunks: chunks,
        },
      },
    },
    preview: {
      port: 3000,
      open: "http://localhost:8080/landing.html",
    },
    resolve: {
      alias: {
        "@parent": path.resolve(__dirname, "."),
        "@app1": path.resolve(__dirname, "./packages/app1"),
        "@app2": path.resolve(__dirname, "./packages/app2"),
        "@app3": path.resolve(__dirname, "./packages/app3")
      },
    },
  });
};

To collect cypress code coverage, I am instrumenting code during the build stage (before running e2e tests) using npm run preview which happens with the help of vite-plugin-istanbul. When I run e2e tests using npm run e2e:open I can see the instrumented code in window.__coverage__ in Test iframe but it isn't picked up by cypress-coverage.

⚠️ file /Users/abc/projects/myapp/.nyc_output/out.json has no coverage information
[1] Did you fet to instrument your web application? Read https://github/cypress-io/code-coverage#instrument-your-application
[1]   code-coverage ⚠️ file /Users/abc/projects/myapp/.nyc_output/out.json has no coverage information +18s

When I run npm run preview, the cwd is packages/app1. As I want to collect coverage for all src files in all packages, I have given cwd:"../.." in vite.config.js but still no luck.

Share Improve this question edited Feb 14 at 5:59 DarkBee 15.6k8 gold badges72 silver badges116 bronze badges asked Feb 13 at 17:00 RollADieRollADie 1794 silver badges14 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 0

I don't have a monorepo, so I am not 100% sure if my input will fix your issue, but it's a Typescript + React + Vite Application.

I use cross-env to pass a variables inline in the package.json script

{
  "cy:run:coverage": "cross-env VITE_APP_ENV=testing nyc cypress run --component",
}

What the VITE_APP_ENV does in the vite config file is: (only showing partially)

  plugins: [
      react(),
      tsconfigPaths(),
      // only necessary on production
      isProduction && viteStaticCopy(staticFolderCopyOptions),

      // code coverage for cypress
      isTesting &&
        istanbul({
          cypress: true,
          include: ['src/**/*.{ts,tsx}'],
          forceBuildInstrument: true,
          nycrcPath: './.nycrc',
          exclude: [
            'node_modules',
            'node_modules/core-js',
            'node_modules/webpack/buildin'
          ],
          extension: ['.ts', '.tsx']
        })
    ],

And my nycrc file configuration:

{
    "extends": "@istanbuljs/nyc-config-typescript",
    "include": [
        "src/**/*.ts",
        "src/**/*.tsx"
    ],
    "exclude": [
        "cypress.config.cjs",
        ".next/**/*",
        "cypress/**/*",
        "node_modules"
    ],
    "check-coverage": true,
    "branches": "85",
    "functions": "85",
    "lines": "85"
}

Maybe you don't need the typescript part of my implementation, but you need to run nyc cypress run --component or nyc cypress open

It should be the same when running in e2e mode.

-- edit -- Fot to add my cypress .cjs config file

const { defineConfig } = require('cypress');

module.exports = defineConfig({
  component: {
    devServer: {
      framework: 'react',
      bundler: 'vite'
    },
    setupNodeEvents(on, config) {
      require('@cypress/code-coverage/task')(on, config);
      return config;
    }
  },
  e2e: {
    setupNodeEvents(on, config) {
      require('@cypress/code-coverage/task')(on, config);
      return config;
    },
    viewportHeight: 800,
    viewportWidth: 1280,
    video: false,
    specPattern: '**/*/e2e/**/*.spec.ts',
    baseUrl: 'http://localhost:3009',
    chromeWebSecurity: false
  }
});

本文标签: javascriptTest coverage not reportedinstrumentedStack Overflow