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

TypeError [ERR_UNKNOWN_ENCODING]: Unknown encoding: base64url is thrown in vite dev server

Open stevez opened this issue 3 years ago • 5 comments

How to reproduce:

  1. code example repo: https://github.com/stevez/playwright-test-coverage/tree/bgotink-coveage-lib-vite-integration git clone https://github.com/stevez/playwright-test-coverage.git git checkout bgotink-coveage-lib-vite-integration
  2. npm install
  3. npx playwright install
  4. npm run test

Then you will get following error:

(node:53635) UnhandledPromiseRejectionWarning: TypeError [ERR_UNKNOWN_ENCODING]: Unknown encoding: base64url at fromString (buffer.js:454:13) at Function.from (buffer.js:308:12) at getSourceMap (/Users/s5474013/github/playwright-test-coverage/node_modules/@bgotink/playwright-coverage/lib/data.js:51:26) at CoverageWorker._CoverageWorker_convert (/Users/s5474013/github/playwright-test-coverage/node_modules/@bgotink/playwright-coverage/lib/worker.js:74:123) (Use node --trace-warnings ... to show where the warning was created) (node:53635) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag --unhandled-rejections=strict (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1) (node:53635) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code. (node:53635) UnhandledPromiseRejectionWarning: TypeError [ERR_UNKNOWN_ENCODING]: Unknown encoding: base64url at fromString (buffer.js:454:13) at Function.from (buffer.js:308:12) at getSourceMap (/Users/s5474013/github/playwright-test-coverage/node_modules/@bgotink/playwright-coverage/lib/data.js:51:26) at CoverageWorker._CoverageWorker_convert (/Users/s5474013/github/playwright-test-coverage/node_modules/@bgotink/playwright-coverage/lib/worker.js:74:123) (node:53635) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag --unhandled-rejections=strict (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 2) (node:53635) UnhandledPromiseRejectionWarning: TypeError [ERR_UNKNOWN_ENCODING]: Unknown encoding: base64url at fromString (buffer.js:454:13) at Function.from (buffer.js:308:12) at getSourceMap (/Users/s5474013/github/playwright-test-coverage/node_modules/@bgotink/playwright-coverage/lib/data.js:51:26) at CoverageWorker._CoverageWorker_convert (/Users/s5474013/github/playwright-test-coverage/node_modules/@bgotink/playwright-coverage/lib/worker.js:74:123) (node:53635) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag --unhandled-rejections=strict (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 3) (node:53635) UnhandledPromiseRejectionWarning: TypeError [ERR_UNKNOWN_ENCODING]: Unknown encoding: base64url at fromString (buffer.js:454:13) ✓ [Chrome] › e2e/App2.test.ts:7:1 › use Turquoise as a background color (2s) at getSourceMap (/Users/s5474013/github/playwright-test-coverage/node_modules/@bgotink/playwright-coverage/lib/data.js:51:26) at CoverageWorker._CoverageWorker_convert (/Users/s5474013/github/playwright-test-coverage/node_modules/@bgotink/playwright-coverage/lib/worker.js:74:123) (node:53635) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag --unhandled-rejections=strict (see h ✓ [Chrome] › e2e/App.test.ts:11:1 › use Red as a background color (477ms)

3 passed (4s) Error in reporter TypeError [ERR_UNKNOWN_ENCODING]: Unknown encoding: base64url at fromString (buffer.js:454:13) at Function.from (buffer.js:308:12) at getSourceMap (/Users/s5474013/github/playwright-test-coverage/node_modules/@bgotink/playwright-coverage/lib/data.js:51:26) at CoverageWorker._CoverageWorker_convert (/Users/s5474013/github/playwright-test-coverage/node_modules/@bgotink/playwright-coverage/lib/worker.js:74:123)

==================================== I understand your library works in the webpack dev server: I have another branch confirmed this, even the coverage number is different with the number in the main branch: (https://github.com/stevez/playwright-test-coverage/tree/bgotink-coverage-lib), But since I want to use the vite server, which source code are not bundled, I think this might cause the issue? I am not familiar with the v8 coverage format yet, maybe you can provide some insight? My original plan was simple: in order to support coverage in vite, playwright tests just output the v8 format json file, then use c8 to generate the istanbul result -- it sounds easy, but the number is not correct, you can check my another branch for the demo: https://github.com/stevez/playwright-test-coverage/tree/v8-coverage.

Either you can fix the issue to support vite, or any suggestion will be appreciated.

stevez avatar Apr 08 '22 02:04 stevez

It appears the base64url encoding was added in node ≥ 14.18.0 (source). Is it feasible for you to update to a newer version of node?

I could work around it for node 12. However, support for node 12 is ending at the end of this month so I'd rather not have to spend time on that.

bgotink avatar Apr 08 '22 16:04 bgotink

I upgraded my node to 16 and it works and coverage report is generated, here is the code example: https://github.com/stevez/playwright-test-coverage/tree/bgotink-coveage-lib-vite-integration

But I do found some issues: Screen Shot 2022-04-08 at 8 38 20 PM Screen Shot 2022-04-08 at 8 38 38 PM

  1. I don't know why import statements are marked as uncovered;
  2. Another strange thing is '8x', on the left side of the bar, which is not possible, since I only have 3 test cases. For details about the report, check the attached zip file. coverage.zip
  3. I got some warning on the console output: (Use node --trace-deprecation ... to show where the warning was created) (node:38060) [DEP0005] DeprecationWarning: Buffer() is deprecated due to security and usability issues. Please use the Buffer.alloc(), Buffer.allocUnsafe(), or Buffer.from() methods instead.

Thanks

stevez avatar Apr 09 '22 00:04 stevez

  1. I don't know why import statements are marked as uncovered;

If you hover over the uncovered line you'll see what is uncovered. It says "branch not covered".

screenshot of a tooltip saying 'branch not covered' in the coverage report

Looking at the javascript code that is generated by vite this makes sense:

import __vite__cjsImport0_react from "/node_modules/.vite/deps/react.js?v=90b50f0a"; const React = __vite__cjsImport0_react.__esModule ? __vite__cjsImport0_react.default : __vite__cjsImport0_react;

One of those two branches will always be uncovered, because the shape of the react module isn't changing.

  1. Another strange thing is '8x', on the left side of the bar, which is not possible, since I only have 3 test cases.

Indeed, but the code is executed multiple times in a single case. For example, if I edit the test that switches the colour to red so it switches the colour back to turquoise, the numbers go up.

test('use Red as a background color', async ({ page }) => {
  await page.click("text=Red")
  await page.waitForSelector("text=#e74c3c")
  await page.click("text=Turquoise")
  await page.waitForSelector("text=#1abc9c")
});
screenshot of the coverage report showing higher numbers than the original
  1. I got some warning on the console output: (Use node --trace-deprecation ... to show where the warning was created) (node:38060) [DEP0005] DeprecationWarning: Buffer() is deprecated due to security and usability issues. Please use the Buffer.alloc(), Buffer.allocUnsafe(), or Buffer.from() methods instead.

Playwright itself uses an older version of source-map-support that calls new Buffer (https://github.com/microsoft/playwright/pull/11945). You'll see this warning even if you don't use the coverage package. You're probably only seeing it for the first time now because you updated your node version.

bgotink avatar Apr 09 '22 09:04 bgotink

Hi @bgotink, I just realize that v8 coverage is based on the 'generated source code', not the original one, is it possible to map to the original one? how about the base64 source map url? is it for the "generated source" or the "original source"?

And I did some digging: in branch "v8-coverage" of my example repo: (https://github.com/stevez/playwright-test-coverage/tree/v8-coverage) I did some experiments: for every test, playwright will generate 1 v8 coverage json ( saved in the coverage/tmp folder), and 1 v8 converted istanbul json file (saved in .nyc_output) folder. Solution 1: If I merge all the converted istanbul json files by running "npx nyc report --reporter=text --reporter=html", then generated the result will match the result using your plugin, here are the screen shots: v8_to_istanbul_1 v8_to_istanbul_2 v8_to_istanbul_3

Solution 2: But If I try to merge all the v8 json files under the coverage/tmp folder by using command "npx c8 report", then the result is quite different, v8_1 v8_2 v8_3

and I don't think this result is correct, it is even worse than the solution 1. Could you give me some insight of what could cause the issue?

And for the warning I never seen that before except using your plugin, I noticed that your plugin use the old version of playwright (1.14), do you think it might be the reason?

So far I tried the different approach to make the playwright coverage working in the vite, finally I just get it working using babel plugin, but I really want the v8 coverage working, I wonder maybe you could help me on this.

Thanks a lot.

stevez avatar Apr 17 '22 03:04 stevez

@lukeapage I saw your comments about playwright v8 coverage issue from here, https://github.com/istanbuljs/puppeteer-to-istanbul/issues/18#issuecomment-585909660, could you provide some code example how you resolve the playwright v8 raw information? Thanks

stevez avatar Apr 17 '22 04:04 stevez