AI agents: read this page as markdown at /docs/how-to/enable-source-coverage.md, or start from the full AI-readable index at /llms.txt.

Viewing source coverage information in Meticulous

Meticulous can be set up to show you what parts of your code are being tested by us. In order to use this feature you must be serving source maps for your code in at least some of the environments you're testing against (for instance, if building source maps significantly slows down your build you could do this only on pushes to your main branch to avoid delaying PR runs).

How can I view my source coverage?

To view your coverage information, visit your project's landing page on Meticulous (that is, the Overview tab). From there click the View coverage & snapshots button, and select the Sources tab. You'll see a list of all the files in your project, and for each file you'll see a percentage of the lines in that file that are covered by your tests. You can click on a file to see the exact lines that are covered and not covered.

How can I serve source maps so Meticulous finds them?

Meticulous will autodetect your source maps in three different ways (you only need to do one of these):

  1. You serve the source map in the same directory as the file it corresponds to, with the same name as the file, but with a .map extension added at the end. For instance, if you have a file https://mysite.com/static/assets/index.js then you should serve the source map at https://mysite.com/static/assets/index.js.map.
  2. You have a sourceMappingURL comment at the end of your file that points to the source map as documented here.
  3. You set the SourceMap HTTP header on the response that serves the file to point to the source map as documented here.

CSS source maps

Meticulous also reports which of your stylesheets each test covered. Doing that needs a source map for the bundled CSS your app loaded, which is a separate artifact from your JavaScript source maps — turning source maps on for JavaScript does not necessarily produce one. Meticulous finds a CSS source map in the same three ways listed above: a .map file served next to the CSS asset, a sourceMappingURL comment at the end of the stylesheet, or a SourceMap response header.

Vite

Vite does not emit CSS source maps for production builds at all (vitejs/vite#2830), and build.sourcemap: true covers JavaScript only — it does nothing for CSS. Without a CSS source map a bundled stylesheet is opaque to us, and its coverage cannot be attributed to any file in your repository.

Our plugin closes that gap. It reconstructs a <asset>.css.map for every CSS asset your build emits, and appends the sourceMappingURL comment that points at it:

npm install @alwaysmeticulous/recorder-plugin@latest --save-dev
// vite.config.ts
import CssSourcemapPlugin from "@alwaysmeticulous/recorder-plugin/css-sourcemap";
import { defineConfig } from "vite";

export default defineConfig({
  plugins: [CssSourcemapPlugin()],
});

The same plugin is available as the named export cssSourcemapPlugin if you prefer. It is independent of the recorder-injection plugin in the same package, so you can use either or both, and it works under Rolldown — used by both the rolldown-vite package and Vite 8 — as well as under stock Vite.

If your Vite project lives in a subdirectory rather than at the root of your repository, pass root so that the emitted source paths match the paths Meticulous sees:

CssSourcemapPlugin({ root: path.resolve(__dirname, "../..") });

How precise is the attribution?

Every stylesheet is attributed to the file it came from. Line-level accuracy depends on the stylesheet:

  1. Plain CSS in its own file maps line for line.
  2. Sass/SCSS and Less map approximately — Vite drops preprocessor maps in production.
  3. Tailwind @imports map to the imported file and line for rules the plugin can still find in the compiled CSS. Generated utilities stay on the Tailwind entry, not on the className that produced them.
  4. A non-Tailwind @import that Vite inlines still gets the right file, but line numbers below the import can shift.

File-level attribution is enough to see which stylesheet a change touched. Tailwind imported rules also get line-level maps; utilities do not.

The tradeoff: CSS minification

The plugin disables Vite's CSS minification, and that is what makes the emitted maps accurate — Vite minifies a CSS asset after the plugin has recorded where each stylesheet landed inside it. Measured on two real apps, the shipped CSS grew by about 11% gzipped on a React and Mantine app, and about 6% on a Tailwind app, with build time within noise. The .css.map files themselves are only fetched by tooling and never on a page load, so they add nothing to what your users download.

Because of that cost, enable the plugin on the build whose coverage Meticulous collects rather than on every production build. You can keep minification on with disableCssMinify: false, but then the plugin emits no map at all and warns, rather than emitting a partial one that would attribute some stylesheets' rules to their neighbours.

Monorepos

If you're using a monorepo, you'll need to build source maps for each package in your monorepo that your app depends on.

For example, if your app is within apps/frontend and you have a package packages/utils that the app depends on, you'll need to build source maps for both of these packages. You might need to adjust your build process to load source maps for your dependencies, e.g. by using source-map-loader in your webpack config.

Example Next.js setup

  1. Enable source maps generation in your dependent packages. packages/utils/tsconfig.json:
    {
      ...
      "sourceMap": true,
      "declarationMap": true
    }
    
  2. Install source-map-loader in your Next.js project:
    npm install --save-dev source-map-loader <OR>
    yarn add --dev source-map-loader <OR>
    pnpm add --save-dev source-map-loader
    
  3. Add the following to your Next.js project's next.config.js in order to load source maps from your monorepo packages:
    module.exports = {
      ...
      webpack: (config, { isServer }) => {
        // Ensure TypeScript source maps from monorepo packages work correctly
        config.module.rules.push({
          test: /\.js$/,
          use: ['source-map-loader'],
          enforce: 'pre',
        });
    
        // Silence source map parsing warnings.
        config.ignoreWarnings = [
          ...(config.ignoreWarnings || []),
          /Failed to parse source map/,
        ];
    
        return config;
      },
    };
    

Where can I reach out for support?

Reach out to support@meticulous.ai and we'll be happy to help.