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

chore: replace karma with wpt runner in user-interaction #2005

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

SimenB
Copy link
Contributor

@SimenB SimenB commented Mar 8, 2024

Which problem is this PR solving?

Following up #1816 for @opentelemetry/instrumentation-user-interaction

Short description of the changes

Migrating another module.

I'm getting the following error locally - it looks like something with my local env, so I thought to open a PR before digging too much more.

 ❌ TypeError: this._wrap is not a function 
      at XMLHttpRequestInstrumentation.enable (../../../node_modules/@opentelemetry/instrumentation-xml-http-request/src/xhr.ts:527:9)
      at XMLHttpRequestInstrumentation.InstrumentationBase [as constructor] (../../../node_modules/@opentelemetry/instrumentation/src/platform/browser/instrumentation.ts:35:11)
      at new XMLHttpRequestInstrumentation (../../../node_modules/@opentelemetry/instrumentation-xml-http-request/src/xhr.ts:92:4)
      at registerTestInstrumentations (test/userInteraction.nozone.test.ts:73:10)
      at Ka.<anonymous> (test/userInteraction.nozone.test.ts:103:6)

@SimenB
Copy link
Contributor Author

SimenB commented Mar 8, 2024

Hmm, ok, fails with the same error here 🤔 Any ideas what it might be? Immediate suspect from my side is that rollup/eslint bundles differently than webpack when it comes to browser/non-browser and we somehow get the wrong version?

Copy link

codecov bot commented Apr 2, 2024

Codecov Report

Merging #2005 (db3007e) into main (dfb2dff) will decrease coverage by 0.69%.
Report is 29 commits behind head on main.
The diff coverage is n/a.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2005      +/-   ##
==========================================
- Coverage   90.97%   90.29%   -0.69%     
==========================================
  Files         146      139       -7     
  Lines        7492     6891     -601     
  Branches     1502     1379     -123     
==========================================
- Hits         6816     6222     -594     
+ Misses        676      669       -7     

see 14 files with indirect coverage changes

Copy link
Contributor

@trentm trentm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I get the same ❌ TypeError: this._wrap is not a function when attempting npm run test:browser locally.

https://gist.github.com/trentm/0ac028d3d343ffb83a7398540c3a05ae

@@ -192,7 +192,7 @@
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0
https://www.apache.org/licenses/LICENSE-2.0
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change should be reverted. The LICENSE files are meant to be a verbatim copy of https://www.apache.org/licenses/LICENSE-2.0.txt

@trentm
Copy link
Contributor

trentm commented May 30, 2024

I get the same ❌ TypeError: this._wrap is not a function when attempting npm run test:browser locally.

I spent a little time getting further on this, but I don't have the time to get to a conclusion.

Adding some debug prints (marked with "XXX" in the output) we see that the imported shimmer module does not have the methods expected:

% npm run test:browser
...
test/userInteraction.test.ts:

 🚧 Browser logs:
      XXX /Users/trentm/tm/opentelemetry-js-contrib10/node_modules/@opentelemetry/instrumentation/build/esm/platform/browser/instrumentation.js InstrumentationBase ctor
      XXX shimmer is: { __moduleExports: [Function: shimmer], default: [Function: shimmer] }
      XXX _wrap:  undefined

 ❌ TypeError: this._wrap is not a function
      at UserInteractionInstrumentation.enable (src/instrumentation.ts:601:11)
      at new InstrumentationBase (../../../node_modules/@opentelemetry/instrumentation/src/platform/browser/instrumentation.ts:36:5)
      at new UserInteractionInstrumentation (src/instrumentation.ts:71:4)
      at registerTestInstrumentations (test/userInteraction.test.ts:69:39)
      at Ka.<anonymous> (test/userInteraction.test.ts:111:6)

 ❌ TypeError: Cannot read properties of undefined (reading 'disable')
      at Ka.<anonymous> (test/userInteraction.test.ts:124:37)

@opentelemetry/instrumentation is doing import * as shimmer from 'shimmer';, then attempting to use shimmer.wrap et al.
https://github.com/open-telemetry/opentelemetry-js/blob/82b7526b028a34a23936016768f37df05effcd59/experimental/packages/opentelemetry-instrumentation/src/instrumentation.ts#L29-L80

In the browser tests, IIUC, we are running as an ES Module (modulo the other issue that the "build/esm/..." outputs are not really valid ES modules; but good enough for bundlers), so:

  • @opentelemetry/instrumentation/build/esm/platform/browser/instrumentation.js does import * as shimmer from 'shimmer';

  • shimmer is a CommonJS module. (Q: I guess the browser tests here are using node rather than running in the browser? Or perhaps this is because of rollup's nodeResolve in its config?) Assuming I'm right that shimmer is being loaded by node, then this will be using CJS-compatibility layer in Node's ESM loader:

https://nodejs.org/api/esm.html#interoperability-with-commonjs

When importing CommonJS modules [...] named exports may be available, provided by static analysis as a convenience for better ecosystem compatibility.

The current module.exports pattern in shimmer is one that Node's "static analysis" doesn't work on for getting named exports:
https://github.com/othiym23/shimmer/blob/b2b29d760aa664767f71f37dbcbfac0b9250421b/index.js#L116-L121

  • If I change shimmer/index.js to a pattern that works with that static analysis:
--- node_modules/shimmer/index.js.orig	2024-05-30 11:47:35
+++ node_modules/shimmer/index.js	2024-05-30 12:01:15
@@ -113,10 +113,9 @@
   })
 }

-shimmer.wrap = wrap
-shimmer.massWrap = massWrap
-shimmer.unwrap = unwrap
-shimmer.massUnwrap = massUnwrap
-
 module.exports = shimmer
+module.exports.wrap = wrap
+module.exports.massWrap = massWrap
+module.exports.unwrap = unwrap
+module.exports.massUnwrap = massUnwrap

then I get I further in tests.
(I only noticed this because Fastify had an almost identical change waaaay back for the exact same ESM->CJS static analysis issue: https://github.com/fastify/fastify/pull/2590/files#diff-a36b53a0e851347821d855f09722921b64d2792750d1deaab126fe54964498a9)

After this local change the XXX shimmer is debug print is now:

      XXX shimmer is: {
        __moduleExports: [Function: shimmer],
        default: [Function: shimmer],
        massUnwrap: [Function: massUnwrap],
        massWrap: [Function: massWrap],
        unwrap: [Function: unwrap],
        wrap: [Function: wrap]
      }

test run after my local changes

npm run test:browser
% npm run test:browser

> @opentelemetry/instrumentation-user-interaction@0.36.0 test:browser
> wtr --coverage


test/userInteraction.test.ts:

 🚧 Browser logs:
      TypeError: Cannot read properties of undefined (reading '0')
        at test/userInteraction.test.ts:137:68
        at timer (../../../node_modules/zone.js/fesm2015/zone.js:2564:41)
        at ZoneDelegate.invokeTask (../../../node_modules/zone.js/fesm2015/zone.js:409:31)
        at Zone.runTask (../../../node_modules/zone.js/fesm2015/zone.js:181:47)
        at Zone.patchRunTask (src/instrumentation.ts:524:26)
        at invokeTask (../../../node_modules/zone.js/fesm2015/zone.js:490:34)
        at ZoneTask.invoke (../../../node_modules/zone.js/fesm2015/zone.js:479:48)
        at data.args.<computed> (../../../node_modules/zone.js/fesm2015/zone.js:2544:32)
      {
        name: 'AssertionError',
        message: 'should not export more then one span: expected +0 to equal 1',
        showDiff: true,
        actual: 0,
        expected: 1,
        operator: 'strictEqual',
        stack: 'AssertionError: should not export more then one span: expected +0 to equal 1\n' +
          '    at http://localhost:8000/test/userInteraction.test.ts?wtr-session-id=Baf3wGtLzc9WUGkgZCogz:111:18\n' +
          '    at timer (http://localhost:8000/__wds-outside-root__/3/node_modules/zone.js/fesm2015/zone.js:2564:41)\n' +
          '    at ZoneDelegate.invokeTask (http://localhost:8000/__wds-outside-root__/3/node_modules/zone.js/fesm2015/zone.js:409:31)\n' +
          '    at Zone.runTask (http://localhost:8000/__wds-outside-root__/3/node_modules/zone.js/fesm2015/zone.js:181:47)\n' +
          '    at Zone.patchRunTask (http://localhost:8000/src/instrumentation.ts:403:27)\n' +
          '    at invokeTask (http://localhost:8000/__wds-outside-root__/3/node_modules/zone.js/fesm2015/zone.js:490:34)\n' +
          '    at ZoneTask.invoke (http://localhost:8000/__wds-outside-root__/3/node_modules/zone.js/fesm2015/zone.js:479:48)\n' +
          '    at data.args.<computed> (http://localhost:8000/__wds-outside-root__/3/node_modules/zone.js/fesm2015/zone.js:2544:32)'
      }
      {
        name: 'AssertionError',
        message: 'should export 2 spans: expected 1 to equal 2',
        showDiff: true,
        actual: 1,
        expected: 2,
        operator: 'strictEqual',
        stack: 'AssertionError: should export 2 spans: expected 1 to equal 2\n' +
          '    at http://localhost:8000/test/userInteraction.test.ts?wtr-session-id=Baf3wGtLzc9WUGkgZCogz:136:20\n' +
          '    at timer (http://localhost:8000/__wds-outside-root__/3/node_modules/zone.js/fesm2015/zone.js:2564:41)\n' +
          '    at ZoneDelegate.invokeTask (http://localhost:8000/__wds-outside-root__/3/node_modules/zone.js/fesm2015/zone.js:409:31)\n' +
          '    at Zone.runTask (http://localhost:8000/__wds-outside-root__/3/node_modules/zone.js/fesm2015/zone.js:181:47)\n' +
          '    at Zone.patchRunTask (http://localhost:8000/src/instrumentation.ts:403:27)\n' +
          '    at invokeTask (http://localhost:8000/__wds-outside-root__/3/node_modules/zone.js/fesm2015/zone.js:490:34)\n' +
          '    at ZoneTask.invoke (http://localhost:8000/__wds-outside-root__/3/node_modules/zone.js/fesm2015/zone.js:479:48)\n' +
          '    at data.args.<computed> (http://localhost:8000/__wds-outside-root__/3/node_modules/zone.js/fesm2015/zone.js:2544:32)'
      }
      {
        name: 'AssertionError',
        message: 'should export 2 spans: expected 1 to equal 2',
        showDiff: true,
        actual: 1,
        expected: 2,
        operator: 'strictEqual',
        stack: 'AssertionError: should export 2 spans: expected 1 to equal 2\n' +
          '    at http://localhost:8000/test/userInteraction.test.ts?wtr-session-id=Baf3wGtLzc9WUGkgZCogz:163:20\n' +
          '    at timer (http://localhost:8000/__wds-outside-root__/3/node_modules/zone.js/fesm2015/zone.js:2564:41)\n' +
          '    at ZoneDelegate.invokeTask (http://localhost:8000/__wds-outside-root__/3/node_modules/zone.js/fesm2015/zone.js:409:31)\n' +
          '    at Zone.runTask (http://localhost:8000/__wds-outside-root__/3/node_modules/zone.js/fesm2015/zone.js:181:47)\n' +
          '    at Zone.patchRunTask (http://localhost:8000/src/instrumentation.ts:403:27)\n' +
          '    at invokeTask (http://localhost:8000/__wds-outside-root__/3/node_modules/zone.js/fesm2015/zone.js:490:34)\n' +
          '    at ZoneTask.invoke (http://localhost:8000/__wds-outside-root__/3/node_modules/zone.js/fesm2015/zone.js:479:48)\n' +
          '    at data.args.<computed> (http://localhost:8000/__wds-outside-root__/3/node_modules/zone.js/fesm2015/zone.js:2544:32)'
      }

 ❌ UserInteractionInstrumentation > when zone.js is available > should ignore timeout when nothing happens afterwards
      Error: Uncaught TypeError: Cannot read properties of undefined (reading '0') (http://localhost:8000/__wds-outside-root__/3/node_modules/zone.js/fesm2015/zone.js:185)
        at wrapFn (../../../node_modules/zone.js/fesm2015/zone.js:760:22)
        at ZoneDelegate.invokeTask (../../../node_modules/zone.js/fesm2015/zone.js:409:31)
        at Zone.runTask (../../../node_modules/zone.js/fesm2015/zone.js:181:47)
        at Zone.patchRunTask (src/instrumentation.ts:524:26)
        at ZoneTask.invokeTask [as invoke] (../../../node_modules/zone.js/fesm2015/zone.js:490:34)
        at invokeTask (../../../node_modules/zone.js/fesm2015/zone.js:1603:14)
        at globalZoneAwareCallback (../../../node_modules/zone.js/fesm2015/zone.js:1629:17)

 ❌ UserInteractionInstrumentation > when zone.js is available > should ignore periodic tasks
      Error: Uncaught AssertionError: should not export more then one span: expected +0 to equal 1 (http://localhost:8000/__wds-outside-root__/3/node_modules/zone.js/fesm2015/zone.js:185)
        at wrapFn (../../../node_modules/zone.js/fesm2015/zone.js:760:22)
        at ZoneDelegate.invokeTask (../../../node_modules/zone.js/fesm2015/zone.js:409:31)
        at Zone.runTask (../../../node_modules/zone.js/fesm2015/zone.js:181:47)
        at Zone.patchRunTask (src/instrumentation.ts:524:26)
        at ZoneTask.invokeTask [as invoke] (../../../node_modules/zone.js/fesm2015/zone.js:490:34)
        at invokeTask (../../../node_modules/zone.js/fesm2015/zone.js:1603:14)
        at globalZoneAwareCallback (../../../node_modules/zone.js/fesm2015/zone.js:1629:17)

 ❌ UserInteractionInstrumentation > when zone.js is available > should handle task with navigation change
      Error: Uncaught AssertionError: should export 2 spans: expected 1 to equal 2 (http://localhost:8000/__wds-outside-root__/3/node_modules/zone.js/fesm2015/zone.js:185)
        at wrapFn (../../../node_modules/zone.js/fesm2015/zone.js:760:22)
        at ZoneDelegate.invokeTask (../../../node_modules/zone.js/fesm2015/zone.js:409:31)
        at Zone.runTask (../../../node_modules/zone.js/fesm2015/zone.js:181:47)
        at Zone.patchRunTask (src/instrumentation.ts:524:26)
        at ZoneTask.invokeTask [as invoke] (../../../node_modules/zone.js/fesm2015/zone.js:490:34)
        at invokeTask (../../../node_modules/zone.js/fesm2015/zone.js:1603:14)
        at globalZoneAwareCallback (../../../node_modules/zone.js/fesm2015/zone.js:1629:17)

 ❌ UserInteractionInstrumentation > when zone.js is available > should handle task with timeout and async operation
      Error: Uncaught AssertionError: should export 2 spans: expected 1 to equal 2 (http://localhost:8000/__wds-outside-root__/3/node_modules/zone.js/fesm2015/zone.js:185)
        at wrapFn (../../../node_modules/zone.js/fesm2015/zone.js:760:22)
        at ZoneDelegate.invokeTask (../../../node_modules/zone.js/fesm2015/zone.js:409:31)
        at Zone.runTask (../../../node_modules/zone.js/fesm2015/zone.js:181:47)
        at Zone.patchRunTask (src/instrumentation.ts:524:26)
        at ZoneTask.invokeTask [as invoke] (../../../node_modules/zone.js/fesm2015/zone.js:490:34)
        at invokeTask (../../../node_modules/zone.js/fesm2015/zone.js:1603:14)
        at globalZoneAwareCallback (../../../node_modules/zone.js/fesm2015/zone.js:1629:17)

 ❌ UserInteractionInstrumentation > when zone.js is available > should handle unpatch
      AssertionError: runTask should be unwrapped: expected true to equal false
      + expected - actual

      -true
      +false

      at Ka.<anonymous> (test/userInteraction.test.ts:584:13)

Chrome: |██████████████████████████████| 3/3 test files | 37 passed, 5 failed

Code coverage: 96.04 %
View full coverage report at coverage/lcov-report/index.html

Finished running tests in 1.8s with 5 failed tests.

npm ERR! Lifecycle script `test:browser` failed with error:
npm ERR! Error: command failed
npm ERR!   in workspace: @opentelemetry/instrumentation-user-interaction@0.36.0
npm ERR!   at location: /Users/trentm/tm/opentelemetry-js-contrib10/plugins/web/opentelemetry-instrumentation-user-interaction

So I think a next step would be a PR on shimmer to change that module.exports pattern for usage in ESM loading.

I'm not entirely confident in my analysis here, because I haven't followed the code to understand what test:browser and wtr are doing.

@JamieDanielson
Copy link
Member

So I think a next step would be a PR on shimmer to change that module.exports pattern for usage in ESM loading.

I think this analysis is valid and that is the next step. Looks like there is an open issue for this already too, so other folks have come across it. I'm not sure how active the author is, as there have not been any changes here in several years. But I think it's worth opening the PR with a test and going from there.

@trentm
Copy link
Contributor

trentm commented May 31, 2024

Looks like there is an open issue for this already too

I saw that. Same error, but I wasn't quickly sure if it was exactly the same thing. I think that is a case of the same issue, but on the failed import of names from the module that user was attempting to use shimmer on -- but I'm not sure.

@JamieDanielson
Copy link
Member

@trentm I opened PR 28 on shimmer, would appreciate if you could take a look at that when you get a chance and provide any feedback you may have.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants