rrweb.ts 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. import type {fullSnapshotEvent, incrementalSnapshotEvent, serializedNodeWithId} from 'sentry/utils/replays/types';
  2. import {EventType, NodeType, RecordingFrame} from 'sentry/utils/replays/types';
  3. interface FullSnapshotEvent extends fullSnapshotEvent {
  4. timestamp: number;
  5. }
  6. interface IncrementalSnapshotEvent extends incrementalSnapshotEvent {
  7. timestamp: number;
  8. }
  9. const nextRRWebId = (function () {
  10. let __rrwebID = 0;
  11. return () => ++__rrwebID;
  12. })();
  13. export function RRWebInitFrameEventsFixture({
  14. height = 600,
  15. href = 'http://localhost/',
  16. timestamp,
  17. width = 800,
  18. }: {
  19. timestamp: Date;
  20. height?: number;
  21. href?: string;
  22. width?: number;
  23. }): RecordingFrame[] {
  24. return [
  25. {
  26. type: EventType.DomContentLoaded,
  27. timestamp: timestamp.getTime(), // rrweb timestamps are in ms
  28. data: {},
  29. },
  30. {
  31. type: EventType.Load,
  32. timestamp: timestamp.getTime(), // rrweb timestamps are in ms
  33. data: {},
  34. },
  35. {
  36. type: EventType.Meta,
  37. data: {href, width, height},
  38. timestamp: timestamp.getTime(), // rrweb timestamps are in ms
  39. },
  40. ];
  41. }
  42. export function RRWebFullSnapshotFrameEventFixture({
  43. timestamp,
  44. childNodes = [],
  45. }: {
  46. timestamp: Date;
  47. childNodes?: serializedNodeWithId[];
  48. }): FullSnapshotEvent {
  49. return {
  50. type: EventType.FullSnapshot,
  51. timestamp: timestamp.getTime(),
  52. data: {
  53. initialOffset: {top: 0, left: 0},
  54. node: {
  55. type: NodeType.Document,
  56. id: 0,
  57. childNodes: [
  58. RRWebDOMFrameFixture({
  59. tagName: 'body',
  60. attributes: {
  61. style:
  62. 'margin:0; font-family: -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", Roboto, Ubuntu;',
  63. },
  64. childNodes,
  65. }),
  66. ],
  67. },
  68. },
  69. };
  70. }
  71. export function RRWebIncrementalSnapshotFrameEventFixture({
  72. timestamp,
  73. data,
  74. }: {
  75. timestamp: Date;
  76. data: incrementalSnapshotEvent['data'];
  77. }): IncrementalSnapshotEvent {
  78. return {
  79. type: EventType.IncrementalSnapshot,
  80. timestamp: timestamp.getTime(),
  81. data,
  82. }
  83. }
  84. export function RRWebDOMFrameFixture({
  85. id,
  86. tagName,
  87. attributes,
  88. childNodes,
  89. textContent,
  90. }: {
  91. attributes?: Record<string, string>;
  92. childNodes?: serializedNodeWithId[];
  93. id?: number;
  94. tagName?: string;
  95. textContent?: string;
  96. }): serializedNodeWithId {
  97. id = id ?? nextRRWebId();
  98. if (tagName) {
  99. return {
  100. type: NodeType.Element,
  101. id,
  102. tagName,
  103. attributes: attributes ?? {},
  104. childNodes: childNodes ?? [],
  105. };
  106. }
  107. return {
  108. type: NodeType.Text,
  109. id,
  110. textContent: textContent ?? '',
  111. };
  112. }
  113. export function RRWebHelloWorldFrameFixture() {
  114. return RRWebDOMFrameFixture({
  115. tagName: 'div',
  116. childNodes: [
  117. RRWebDOMFrameFixture({
  118. tagName: 'h1',
  119. attributes: {style: 'text-align: center;'},
  120. childNodes: [
  121. RRWebDOMFrameFixture({
  122. textContent: 'Hello World',
  123. }),
  124. ],
  125. }),
  126. ],
  127. });
  128. }