playwright-coverage icon indicating copy to clipboard operation
playwright-coverage copied to clipboard

Incorrect path for covered files in Next.js & monorepo

Open luixo opened this issue 2 years ago • 0 comments

Hello, Trying to add coverage to Playwright using this package with my monorepo and Next.js (being in <root>/apps/next dir), I stumbled upon having only files from Next.js dir but no files from other packages directories (e.g. <root>/packages/components). Digging down, I found that emitted coverage JSONs look something like this:

{
  "version": 3,
  "file": "../../packages/components/component.tsx",
  "mapping": "...",
  "sources": ["webpack://_N_E/../../packages/components/component.tsx?xxxx"],
  "sourcesContent": ["..."],
  "names": [...],
  "sourceRoot": ""
}

Eventually:

  • this JSON gets to v8-to-istanbul package
  • where the sources[0] is used as a path to resolve a filename (with cut webpack:// part)
  • which results to a join("", "_N_E/../../packages/components/component.tsx")
  • hence ../packages/components/component.tsx losing one level of double dots.

I'm not sure if I can manage this user-land, probably not. Using the same rewritePath on paths in source map could be a good call though passing a function to a worker is not an option I guess.

Let me know if I can give you more details on the issue.

Update: I managed to fix this issue by making this diff:

# data.js
 {
   source,
-  sourceMap: {sourcemap: sourceMap},
+  sourceMap: {
+    ...sourceMap,
+    sourceRoot,
+    sources: await Promise.all(
+      sourceMap.sources.map((relativePath) =>
+        rewritePath({ relativePath })
+      ))
+  },
 },
 path => {

The rewritePath is passed with a proxy of a comlink:

// reporter.js
import { wrap, proxy } from "comlink";
...
const totalCoverage = await this.worker.getTotalCoverage(sourceRoot, this.exclude, proxy(this.rewritePath));

luixo avatar Sep 20 '23 00:09 luixo