replaySpanFrameData.ts 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. import {RawSpanFrame} from 'sentry/utils/replays/types';
  2. type Overwrite<T, U> = Pick<T, Exclude<keyof T, keyof U>> & U;
  3. type TestableFrame<Op extends RawSpanFrame['op']> = Overwrite<
  4. Partial<Extract<RawSpanFrame, {op: Op}>>,
  5. {endTimestamp: Date; startTimestamp: Date}
  6. >;
  7. type MockFrame<Op extends RawSpanFrame['op']> = Extract<RawSpanFrame, {op: Op}>;
  8. function BaseFrame<T extends RawSpanFrame['op']>(
  9. op: T,
  10. fields: TestableFrame<T>
  11. ): MockFrame<T> {
  12. return {
  13. op,
  14. description: fields.description ?? '',
  15. startTimestamp: fields.startTimestamp.getTime() / 1000,
  16. endTimestamp: fields.endTimestamp.getTime() / 1000,
  17. data: fields.data,
  18. } as MockFrame<T>;
  19. }
  20. export function ReplayWebVitalFrameFixture(
  21. fields: TestableFrame<'largest-contentful-paint' | 'cumulative-layout-shift' | 'first-input-delay' | 'interaction-to-next-paint'
  22. >
  23. ): MockFrame<'largest-contentful-paint' | 'cumulative-layout-shift' | 'first-input-delay' | 'interaction-to-next-paint'
  24. > {
  25. return BaseFrame(fields.op ?? 'largest-contentful-paint', {
  26. ...fields,
  27. data: {
  28. nodeId: fields.data?.nodeId,
  29. size: fields.data?.size ?? 0,
  30. value: fields.data?.value ?? 0,
  31. rating: fields.data?.rating ?? "good",
  32. },
  33. });
  34. }
  35. export function ReplayMemoryFrameFixture(
  36. fields: TestableFrame<'memory'>
  37. ): MockFrame<'memory'> {
  38. return BaseFrame('memory', {
  39. ...fields,
  40. data: {
  41. memory: {
  42. jsHeapSizeLimit: fields.data?.memory?.jsHeapSizeLimit ?? 0,
  43. totalJSHeapSize: fields.data?.memory?.totalJSHeapSize ?? 0,
  44. usedJSHeapSize: fields.data?.memory?.usedJSHeapSize ?? 0,
  45. },
  46. },
  47. });
  48. }
  49. export function ReplayNavigationFrameFixture(
  50. fields: TestableFrame<
  51. 'navigation.navigate' | 'navigation.reload' | 'navigation.back_forward'
  52. >
  53. ): MockFrame<'navigation.navigate' | 'navigation.reload' | 'navigation.back_forward'> {
  54. return BaseFrame(fields.op ?? 'navigation.navigate', {
  55. ...fields,
  56. data: {
  57. decodedBodySize: fields.data?.decodedBodySize,
  58. domComplete: fields.data?.domComplete,
  59. domContentLoadedEventEnd: fields.data?.domContentLoadedEventEnd,
  60. domContentLoadedEventStart: fields.data?.domContentLoadedEventStart,
  61. domInteractive: fields.data?.domInteractive,
  62. duration: fields.data?.duration,
  63. encodedBodySize: fields.data?.encodedBodySize,
  64. loadEventEnd: fields.data?.loadEventEnd,
  65. loadEventStart: fields.data?.loadEventStart,
  66. redirectCount: fields.data?.redirectCount,
  67. size: fields.data?.size,
  68. },
  69. });
  70. }
  71. export function ReplayNavigationPushFrameFixture(
  72. fields: TestableFrame<'navigation.push'>
  73. ): MockFrame<'navigation.push'> {
  74. return BaseFrame('navigation.push', {
  75. ...fields,
  76. data: {
  77. previous: fields.data?.previous ?? '/',
  78. },
  79. });
  80. }
  81. export function ReplayPaintFrameFixture(
  82. fields: TestableFrame<'paint'>
  83. ): MockFrame<'paint'> {
  84. return BaseFrame('paint', fields);
  85. }
  86. export function ReplayRequestFrameFixture(
  87. fields: TestableFrame<'resource.fetch' | 'resource.xhr' | 'resource.http'>
  88. ): MockFrame<'resource.fetch' | 'resource.xhr' | 'resource.http'> {
  89. return BaseFrame(fields.op ?? 'resource.xhr', {
  90. ...fields,
  91. data: {
  92. method: fields.data?.method,
  93. requestBodySize: fields.data?.requestBodySize,
  94. responseBodySize: fields.data?.responseBodySize,
  95. statusCode: fields.data?.statusCode,
  96. request: fields.data?.request,
  97. response: fields.data?.response,
  98. },
  99. });
  100. }
  101. export function ReplayResourceFrameFixture(
  102. fields: TestableFrame<
  103. | 'resource.css'
  104. | 'resource.iframe'
  105. | 'resource.img'
  106. | 'resource.link'
  107. | 'resource.other'
  108. | 'resource.script'
  109. >
  110. ): MockFrame<
  111. | 'resource.css'
  112. | 'resource.iframe'
  113. | 'resource.img'
  114. | 'resource.link'
  115. | 'resource.other'
  116. | 'resource.script'
  117. > {
  118. return BaseFrame(fields.op ?? 'resource.other', {
  119. ...fields,
  120. data: {
  121. decodedBodySize: fields.data?.decodedBodySize ?? 0,
  122. encodedBodySize: fields.data?.encodedBodySize ?? 0,
  123. size: fields.data?.size ?? 0,
  124. statusCode: fields.data?.statusCode,
  125. },
  126. });
  127. }