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

console.log from webworker, when using browser runner, does not get captured #7439

Open
6 tasks done
jbms opened this issue Feb 6, 2025 · 3 comments
Open
6 tasks done
Labels
feat: browser Issues and PRs related to the browser runner p2-to-be-discussed Enhancement under consideration (priority) pending triage

Comments

@jbms
Copy link

jbms commented Feb 6, 2025

Describe the bug

When using the browser runner, if a test starts a webworker, and that worker calls console.log, the log messages are not shown as stdout like log messages from the main thread.

The only way I've found to see the log messages is to run in non-headless mode and open the JavaScript console.

Reproduction

https://stackblitz.com/edit/vitest-dev-vitest-oszejgfz?file=test%2Fbasic.test.ts

System Info

N/A

See stackblitz reproduction.

Used Package Manager

npm

Validations

@hi-ogawa
Copy link
Contributor

hi-ogawa commented Feb 7, 2025

EDIT: I mixed up and I initially posted the comment #7440 (comment) here.

Similar to #7440, here is node worker thread version https://stackblitz.com/edit/vitest-dev-vitest-q9nkjrvd?file=test%2Fbasic.test.ts.

This is also a fundamental difference how main and worker tied together on browser and on node. For node worker threads, stdio are reused, so console log shows up automatically in the terminal. To support something similar for browser worker, we need an extra mechanism to send log from worker to main.


Here is an example to proxy logs and unhandled errors using BroadcastChannel https://stackblitz.com/edit/vitest-dev-vitest-yzjj5amy?file=test%2Fbasic.test.ts

// worker.js
const channel = new BroadcastChannel('my-worker-channel');
self.onerror = (event) => {
  channel.postMessage({ type: 'error', payload: event });
};
console.log = (...args) => {
  channel.postMessage({ type: 'log', payload: args });
};

// basic.test.js
const channel = new BroadcastChannel('my-worker-channel');
channel.onmessage = (event) => {
  if (event.data.type === 'error') {
    throw new Error('[Worker error] ' + event.data.payload);
  }
  if (event.data.type === 'log') {
    console.log('[Worker console]', ...event.data.payload);
  }
};
 chromium  Browser runner started at http://localhost:63315/

...
stdout | test/basic.test.ts
[Worker console] Hello
...
 ✓  chromium  test/basic.test.ts (1 test) 32ms
   ✓ create worker
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Unhandled Errors ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯

Vitest caught 1 unhandled error during the test run.
This might cause false positive tests. Resolve unhandled errors to make sure your tests are not affected.

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Error ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
Error: [Worker error] Uncaught Error: Some error not caught
 ❯ channel.onmessage test/basic.test.ts:8:12

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯

@hi-ogawa hi-ogawa added the feat: browser Issues and PRs related to the browser runner label Feb 7, 2025
@jbms
Copy link
Author

jbms commented Feb 7, 2025

Is there a way that vitest can inject some code to do that in every worker automatically? Maybe by monkey patching the Worker global?

@hi-ogawa
Copy link
Contributor

hi-ogawa commented Feb 7, 2025

Yeah, that's probably the plan. Vite uses a special url for worker entry file and we already do this:

{
name: 'vitest:browser:worker',
transform(code, id, _options) {
// https://github.com/vitejs/vite/blob/ba56cf43b5480f8519349f7d7fe60718e9af5f1a/packages/vite/src/node/plugins/worker.ts#L46
if (/(?:\?|&)worker_file&type=\w+(?:&|$)/.test(id)) {
const s = new MagicString(code)
s.prepend('globalThis.__vitest_browser_runner__ = { wrapDynamicImport: f => f() };\n')
return {
code: s.toString(),
map: s.generateMap({ hires: 'boundary' }),
}
}
},
},

@hi-ogawa hi-ogawa added the p2-to-be-discussed Enhancement under consideration (priority) label Feb 11, 2025
@hi-ogawa hi-ogawa moved this to P2 - 2 in Team Board Feb 11, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feat: browser Issues and PRs related to the browser runner p2-to-be-discussed Enhancement under consideration (priority) pending triage
Projects
Status: P2 - 2
Development

No branches or pull requests

2 participants