userEventIntegration.ts 1.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
  1. import * as Sentry from '@sentry/react';
  2. import {fill, isThenable, loadModule} from '@sentry/utils';
  3. export function instrumentUserEvent(): void {
  4. const pkg = loadModule('@testing-library/user-event') as any;
  5. ACTIONS.forEach((action: Action) => _patchAction(pkg.default, action));
  6. }
  7. type Action = (typeof ACTIONS)[number];
  8. const ACTIONS = [
  9. 'click',
  10. 'dblClick',
  11. 'type',
  12. 'clear',
  13. 'tab',
  14. 'hover',
  15. 'unhover',
  16. 'upload',
  17. 'selectOptions',
  18. 'deselectOptions',
  19. 'paste',
  20. 'keyboard',
  21. ];
  22. function _patchAction(userEvent: any, action: Action): void {
  23. fill(userEvent, action, function (orig: () => void | Promise<unknown>) {
  24. return function patchedAction(this: unknown, ...args: unknown[]) {
  25. const span = Sentry.startInactiveSpan({
  26. op: 'user event',
  27. name: action,
  28. onlyIfParent: true,
  29. });
  30. const maybePromise = orig.call(this, ...args);
  31. if (isThenable(maybePromise)) {
  32. return maybePromise.then((res: unknown) => {
  33. span.end();
  34. return res;
  35. });
  36. }
  37. span.end();
  38. return maybePromise;
  39. };
  40. });
  41. }