@openreplay/tracker 11.0.0 → 11.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (92) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/cjs/app/index.d.ts +3 -0
  3. package/cjs/app/index.js +27 -4
  4. package/cjs/index.d.ts +1 -0
  5. package/cjs/index.js +7 -1
  6. package/cjs/modules/Network/fetchProxy.js +4 -2
  7. package/cjs/modules/userTesting/SignalManager.d.ts +29 -0
  8. package/cjs/modules/userTesting/SignalManager.js +83 -0
  9. package/cjs/modules/userTesting/index.d.ts +5 -5
  10. package/cjs/modules/userTesting/index.js +156 -189
  11. package/cjs/modules/userTesting/styles.d.ts +28 -11
  12. package/cjs/modules/userTesting/styles.js +51 -29
  13. package/cjs/modules/userTesting/utils.d.ts +9 -0
  14. package/cjs/modules/userTesting/utils.js +87 -0
  15. package/coverage/clover.xml +1331 -562
  16. package/coverage/coverage-final.json +13 -6
  17. package/coverage/lcov-report/index.html +49 -34
  18. package/coverage/lcov-report/main/app/canvas.ts.html +1 -1
  19. package/coverage/lcov-report/main/app/guards.ts.html +42 -42
  20. package/coverage/lcov-report/main/app/index.html +24 -24
  21. package/coverage/lcov-report/main/app/index.ts.html +1046 -56
  22. package/coverage/lcov-report/main/app/logger.ts.html +1 -1
  23. package/coverage/lcov-report/main/app/messages.gen.ts.html +1 -1
  24. package/coverage/lcov-report/main/app/nodes.ts.html +1 -1
  25. package/coverage/lcov-report/main/app/observer/iframe_observer.ts.html +1 -1
  26. package/coverage/lcov-report/main/app/observer/iframe_offsets.ts.html +1 -1
  27. package/coverage/lcov-report/main/app/observer/index.html +1 -1
  28. package/coverage/lcov-report/main/app/observer/shadow_root_observer.ts.html +1 -1
  29. package/coverage/lcov-report/main/app/observer/top_observer.ts.html +1 -1
  30. package/coverage/lcov-report/main/app/sanitizer.ts.html +1 -1
  31. package/coverage/lcov-report/main/app/session.ts.html +1 -1
  32. package/coverage/lcov-report/main/app/ticker.ts.html +1 -1
  33. package/coverage/lcov-report/main/index.html +11 -11
  34. package/coverage/lcov-report/main/index.ts.html +274 -100
  35. package/coverage/lcov-report/main/modules/Network/beaconProxy.ts.html +1 -1
  36. package/coverage/lcov-report/main/modules/Network/fetchProxy.ts.html +1 -1
  37. package/coverage/lcov-report/main/modules/Network/index.html +1 -1
  38. package/coverage/lcov-report/main/modules/Network/index.ts.html +1 -1
  39. package/coverage/lcov-report/main/modules/Network/networkMessage.ts.html +1 -1
  40. package/coverage/lcov-report/main/modules/Network/utils.ts.html +1 -1
  41. package/coverage/lcov-report/main/modules/Network/xhrProxy.ts.html +1 -1
  42. package/coverage/lcov-report/main/modules/attributeSender.ts.html +1 -1
  43. package/coverage/lcov-report/main/modules/axiosSpy.ts.html +1 -1
  44. package/coverage/lcov-report/main/modules/conditionsManager.ts.html +799 -0
  45. package/coverage/lcov-report/main/modules/connection.ts.html +1 -1
  46. package/coverage/lcov-report/main/modules/console.ts.html +1 -1
  47. package/coverage/lcov-report/main/modules/constructedStyleSheets.ts.html +1 -1
  48. package/coverage/lcov-report/main/modules/cssrules.ts.html +1 -1
  49. package/coverage/lcov-report/main/modules/exception.ts.html +1 -1
  50. package/coverage/lcov-report/main/modules/featureFlags.ts.html +10 -7
  51. package/coverage/lcov-report/main/modules/focus.ts.html +1 -1
  52. package/coverage/lcov-report/main/modules/fonts.ts.html +1 -1
  53. package/coverage/lcov-report/main/modules/img.ts.html +1 -1
  54. package/coverage/lcov-report/main/modules/index.html +27 -12
  55. package/coverage/lcov-report/main/modules/input.ts.html +1 -1
  56. package/coverage/lcov-report/main/modules/mouse.ts.html +1 -1
  57. package/coverage/lcov-report/main/modules/network.ts.html +1 -1
  58. package/coverage/lcov-report/main/modules/performance.ts.html +1 -1
  59. package/coverage/lcov-report/main/modules/scroll.ts.html +1 -1
  60. package/coverage/lcov-report/main/modules/selection.ts.html +1 -1
  61. package/coverage/lcov-report/main/modules/tabs.ts.html +1 -1
  62. package/coverage/lcov-report/main/modules/timing.ts.html +1 -1
  63. package/coverage/lcov-report/main/modules/userTesting/SignalManager.ts.html +370 -0
  64. package/coverage/lcov-report/main/modules/userTesting/dnd.ts.html +10 -22
  65. package/coverage/lcov-report/main/modules/userTesting/index.html +57 -27
  66. package/coverage/lcov-report/main/modules/userTesting/index.ts.html +814 -115
  67. package/coverage/lcov-report/main/modules/userTesting/recorder.ts.html +136 -67
  68. package/coverage/lcov-report/main/modules/userTesting/styles.ts.html +111 -39
  69. package/coverage/lcov-report/main/modules/userTesting/utils.ts.html +364 -0
  70. package/coverage/lcov-report/main/modules/viewport.ts.html +1 -1
  71. package/coverage/lcov-report/main/utils.ts.html +48 -6
  72. package/coverage/lcov-report/webworker/BatchWriter.ts.html +1 -1
  73. package/coverage/lcov-report/webworker/MessageEncoder.gen.ts.html +1 -1
  74. package/coverage/lcov-report/webworker/PrimitiveEncoder.ts.html +1 -1
  75. package/coverage/lcov-report/webworker/QueueSender.ts.html +1 -1
  76. package/coverage/lcov-report/webworker/index.html +5 -5
  77. package/coverage/lcov-report/webworker/index.ts.html +15 -9
  78. package/coverage/lcov.info +2306 -900
  79. package/lib/app/index.d.ts +3 -0
  80. package/lib/app/index.js +27 -4
  81. package/lib/index.d.ts +1 -0
  82. package/lib/index.js +7 -1
  83. package/lib/modules/Network/fetchProxy.js +4 -2
  84. package/lib/modules/userTesting/SignalManager.d.ts +29 -0
  85. package/lib/modules/userTesting/SignalManager.js +80 -0
  86. package/lib/modules/userTesting/index.d.ts +5 -5
  87. package/lib/modules/userTesting/index.js +128 -161
  88. package/lib/modules/userTesting/styles.d.ts +28 -11
  89. package/lib/modules/userTesting/styles.js +50 -28
  90. package/lib/modules/userTesting/utils.d.ts +9 -0
  91. package/lib/modules/userTesting/utils.js +79 -0
  92. package/package.json +1 -1
@@ -1,18 +1,8 @@
1
1
  import * as styles from './styles.js';
2
2
  import Recorder, { Quality } from './recorder.js';
3
3
  import attachDND from './dnd.js';
4
- function createElement(tag, className, styles, textContent, id) {
5
- const element = document.createElement(tag);
6
- element.className = className;
7
- Object.assign(element.style, styles);
8
- if (textContent) {
9
- element.textContent = textContent;
10
- }
11
- if (id) {
12
- element.id = id;
13
- }
14
- return element;
15
- }
4
+ import { generateGrid, generateChevron, createSpinner, createElement, TEST_START, TASK_IND, SESSION_ID, TEST_ID, } from './utils.js';
5
+ import SignalManager from './SignalManager.js';
16
6
  export default class UserTestManager {
17
7
  constructor(app, storageKey) {
18
8
  this.app = app;
@@ -22,80 +12,28 @@ export default class UserTestManager {
22
12
  this.widgetGuidelinesVisible = true;
23
13
  this.widgetTasksVisible = false;
24
14
  this.widgetVisible = true;
15
+ this.isActive = false;
25
16
  this.descriptionSection = null;
26
17
  this.taskSection = null;
27
18
  this.endSection = null;
28
19
  this.stopButton = null;
20
+ this.stopButtonContainer = null;
29
21
  this.test = null;
30
22
  this.testId = null;
31
- this.token = null;
32
- this.durations = {
33
- testStart: 0,
34
- tasks: [],
35
- };
36
- this.signalTask = (taskId, status, answer) => {
37
- if (!taskId)
38
- return console.error('OR: no task id');
39
- const taskStart = this.durations.tasks.find((t) => t.taskId === taskId);
40
- const timestamp = this.app.timestamp();
41
- const duration = taskStart ? timestamp - taskStart.started : 0;
42
- const ingest = this.app.options.ingestPoint;
43
- return fetch(`${ingest}/v1/web/uxt/signals/task`, {
44
- method: 'POST',
45
- headers: {
46
- // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
47
- Authorization: `Bearer ${this.token}`,
48
- },
49
- body: JSON.stringify({
50
- testId: this.testId,
51
- taskId,
52
- status,
53
- duration,
54
- timestamp,
55
- answer,
56
- }),
57
- });
58
- };
59
- this.signalTest = (status) => {
60
- const timestamp = this.app.timestamp();
61
- if (status === 'begin' && this.testId) {
62
- this.app.localStorage.setItem(this.storageKey, this.testId.toString());
63
- this.app.localStorage.setItem('or_uxt_test_start', timestamp.toString());
64
- }
65
- else {
66
- this.app.localStorage.removeItem(this.storageKey);
67
- this.app.localStorage.removeItem('or_uxt_task_index');
68
- this.app.localStorage.removeItem('or_uxt_test_start');
69
- }
70
- const ingest = this.app.options.ingestPoint;
71
- const start = this.durations.testStart || timestamp;
72
- const duration = timestamp - start;
73
- return fetch(`${ingest}/v1/web/uxt/signals/test`, {
74
- method: 'POST',
75
- headers: {
76
- // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
77
- Authorization: `Bearer ${this.token}`,
78
- },
79
- body: JSON.stringify({
80
- testId: this.testId,
81
- status,
82
- duration,
83
- timestamp,
84
- }),
85
- });
86
- };
23
+ this.signalManager = null;
87
24
  this.getTest = (id, token, inProgress) => {
88
25
  this.testId = id;
89
- this.token = token;
90
26
  const ingest = this.app.options.ingestPoint;
91
- fetch(`${ingest}/v1/web/uxt/test/${id}`, {
27
+ return fetch(`${ingest}/v1/web/uxt/test/${id}`, {
92
28
  headers: {
93
29
  Authorization: `Bearer ${token}`,
94
30
  },
95
31
  })
96
32
  .then((res) => res.json())
97
33
  .then(({ test }) => {
34
+ this.isActive = true;
98
35
  this.test = test;
36
+ this.signalManager = new SignalManager(this.app.options.ingestPoint, () => this.app.timestamp(), token, id, this.storageKey, (k, v) => this.app.localStorage.setItem(k, v), (k) => this.app.localStorage.removeItem(k), (k) => this.app.localStorage.getItem(k), () => this.app.getSessionID());
99
37
  this.createGreeting(test.title, test.reqMic, test.reqCamera);
100
38
  if (inProgress) {
101
39
  if (test.reqMic || test.reqCamera) {
@@ -105,6 +43,7 @@ export default class UserTestManager {
105
43
  this.showTaskSection();
106
44
  }
107
45
  })
46
+ .then(() => id)
108
47
  .catch((err) => {
109
48
  console.log('OR: Error fetching test', err);
110
49
  });
@@ -118,24 +57,27 @@ export default class UserTestManager {
118
57
  this.currentTaskIndex = 0;
119
58
  this.userRecorder = new Recorder(app);
120
59
  const sessionId = this.app.getSessionID();
121
- const savedSessionId = this.app.localStorage.getItem('or_uxt_session_id');
60
+ const savedSessionId = this.app.localStorage.getItem(SESSION_ID);
122
61
  if (sessionId !== savedSessionId) {
123
62
  this.app.localStorage.removeItem(this.storageKey);
124
- this.app.localStorage.removeItem('or_uxt_session_id');
125
- this.app.localStorage.removeItem('or_uxt_test_id');
126
- this.app.localStorage.removeItem('or_uxt_task_index');
127
- this.app.localStorage.removeItem('or_uxt_test_start');
63
+ this.app.localStorage.removeItem(SESSION_ID);
64
+ this.app.localStorage.removeItem(TEST_ID);
65
+ this.app.localStorage.removeItem(TASK_IND);
66
+ this.app.localStorage.removeItem(TEST_START);
128
67
  }
129
- const taskIndex = this.app.localStorage.getItem('or_uxt_task_index');
68
+ const taskIndex = this.app.localStorage.getItem(TASK_IND);
130
69
  if (taskIndex) {
131
70
  this.currentTaskIndex = parseInt(taskIndex, 10);
132
- this.durations.testStart = parseInt(this.app.localStorage.getItem('or_uxt_test_start'), 10);
133
71
  }
134
72
  }
73
+ getTestId() {
74
+ return this.testId;
75
+ }
135
76
  createGreeting(title, micRequired, cameraRequired) {
136
77
  const titleElement = createElement('div', 'title', styles.titleStyle, title);
137
- const descriptionElement = createElement('div', 'description', styles.descriptionStyle, 'Welcome, this session will be recorded. You have complete control, and can stop the session at any time.');
138
- const noticeElement = createElement('div', 'notice', styles.noticeStyle, `Please note that your ${micRequired ? 'audio,' : ''} ${cameraRequired ? 'video,' : ''} ${micRequired || cameraRequired ? 'and' : ''} screen will be recorded for research purposes during this test.`);
78
+ const descriptionElement = createElement('div', 'description', styles.descriptionStyle, `Welcome, you're here to help us improve, not to be judged. Your insights matter!\n
79
+ 📹 We're recording this browser tab to learn from your experience.
80
+ 🎤 Please enable mic and camera if asked, to give us a complete picture.`);
139
81
  const buttonElement = createElement('div', 'button', styles.buttonStyle, 'Read guidelines to begin');
140
82
  this.removeGreeting = () => {
141
83
  // this.container.innerHTML = ''
@@ -143,19 +85,24 @@ export default class UserTestManager {
143
85
  void this.userRecorder.startRecording(30, Quality.Standard, micRequired, cameraRequired);
144
86
  }
145
87
  this.container.removeChild(buttonElement);
146
- this.container.removeChild(noticeElement);
147
88
  this.container.removeChild(descriptionElement);
148
89
  this.container.removeChild(titleElement);
149
90
  return false;
150
91
  };
151
92
  buttonElement.onclick = () => {
152
- var _a, _b;
93
+ var _a, _b, _c, _d;
153
94
  this.removeGreeting();
154
- this.durations.testStart = this.app.timestamp();
155
- void this.signalTest('begin');
156
- this.showWidget(((_a = this.test) === null || _a === void 0 ? void 0 : _a.guidelines) || '', ((_b = this.test) === null || _b === void 0 ? void 0 : _b.tasks) || []);
95
+ const durations = (_a = this.signalManager) === null || _a === void 0 ? void 0 : _a.getDurations();
96
+ if (durations && this.signalManager) {
97
+ durations.testStart = this.app.timestamp();
98
+ this.signalManager.setDurations(durations);
99
+ }
100
+ void ((_b = this.signalManager) === null || _b === void 0 ? void 0 : _b.signalTest('begin'));
101
+ this.container.style.fontFamily = `-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"`;
102
+ Object.assign(this.container.style, styles.containerWidgetStyle);
103
+ this.showWidget(((_c = this.test) === null || _c === void 0 ? void 0 : _c.guidelines) || '', ((_d = this.test) === null || _d === void 0 ? void 0 : _d.tasks) || []);
157
104
  };
158
- this.container.append(titleElement, descriptionElement, noticeElement, buttonElement);
105
+ this.container.append(titleElement, descriptionElement, buttonElement);
159
106
  this.bg.appendChild(this.container);
160
107
  document.body.appendChild(this.bg);
161
108
  }
@@ -176,18 +123,25 @@ export default class UserTestManager {
176
123
  });
177
124
  // Create title section
178
125
  const titleSection = this.createTitleSection();
126
+ this.container.style.fontFamily = `-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"`;
179
127
  Object.assign(this.container.style, styles.containerWidgetStyle);
180
128
  const descriptionSection = this.createDescriptionSection(guidelines);
181
129
  const tasksSection = this.createTasksSection(tasks);
182
130
  const stopButton = createElement('div', 'stop_bn_or', styles.stopWidgetStyle, 'Abort Session');
183
- this.container.append(titleSection, descriptionSection, tasksSection, stopButton);
131
+ const stopContainer = createElement('div', 'stop_ct_or', { fontSize: '13px!important' });
132
+ stopContainer.style.fontSize = '13px';
133
+ stopContainer.append(stopButton);
134
+ this.container.append(titleSection, descriptionSection, tasksSection, stopContainer);
184
135
  this.taskSection = tasksSection;
185
136
  this.descriptionSection = descriptionSection;
186
137
  this.stopButton = stopButton;
138
+ this.stopButtonContainer = stopContainer;
187
139
  stopButton.onclick = () => {
140
+ var _a;
188
141
  this.userRecorder.discard();
189
- void this.signalTest('skipped');
142
+ void ((_a = this.signalManager) === null || _a === void 0 ? void 0 : _a.signalTest('skipped'));
190
143
  document.body.removeChild(this.bg);
144
+ window.close();
191
145
  };
192
146
  if (!inProgress) {
193
147
  this.hideTaskSection();
@@ -200,11 +154,20 @@ export default class UserTestManager {
200
154
  var _a;
201
155
  const title = createElement('div', 'title', styles.titleWidgetStyle);
202
156
  const leftIcon = generateGrid();
203
- const titleText = createElement('div', 'title_text', {}, (_a = this.test) === null || _a === void 0 ? void 0 : _a.title);
157
+ const titleText = createElement('div', 'title_text', {
158
+ maxWidth: '19rem',
159
+ overflow: 'hidden',
160
+ textOverflow: 'ellipsis',
161
+ width: '100%',
162
+ fontSize: 16,
163
+ lineHeight: 'auto',
164
+ cursor: 'pointer',
165
+ }, (_a = this.test) === null || _a === void 0 ? void 0 : _a.title);
204
166
  const rightIcon = generateChevron();
205
167
  title.append(leftIcon, titleText, rightIcon);
206
168
  const toggleWidget = (isVisible) => {
207
169
  this.widgetVisible = isVisible;
170
+ this.container.style.fontFamily = `-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"`;
208
171
  Object.assign(this.container.style, this.widgetVisible
209
172
  ? styles.containerWidgetStyle
210
173
  : { border: 'none', background: 'none', padding: 0 });
@@ -222,12 +185,14 @@ export default class UserTestManager {
222
185
  }
223
186
  return isVisible;
224
187
  };
225
- rightIcon.onclick = () => {
188
+ const collapseWidget = () => {
226
189
  Object.assign(rightIcon.style, {
227
190
  transform: this.widgetVisible ? 'rotate(0deg)' : 'rotate(180deg)',
228
191
  });
229
192
  toggleWidget(!this.widgetVisible);
230
193
  };
194
+ titleText.onclick = collapseWidget;
195
+ rightIcon.onclick = collapseWidget;
231
196
  attachDND(this.bg, leftIcon);
232
197
  this.collapseWidget = () => toggleWidget(false);
233
198
  return title;
@@ -235,13 +200,20 @@ export default class UserTestManager {
235
200
  createDescriptionSection(guidelines) {
236
201
  const section = createElement('div', 'description_section_or', styles.descriptionWidgetStyle);
237
202
  const titleContainer = createElement('div', 'description_s_title_or', styles.sectionTitleStyle);
238
- const title = createElement('div', 'title', {}, 'Introduction & Guidelines');
203
+ const title = createElement('div', 'title', {
204
+ fontSize: 13,
205
+ fontWeight: 500,
206
+ lineHeight: 'auto',
207
+ }, 'Introduction & Guidelines');
239
208
  const icon = createElement('div', 'icon', styles.symbolIcon, '-');
240
209
  const content = createElement('div', 'content', styles.contentStyle);
241
210
  const descriptionC = createElement('div', 'text_description', {
242
211
  maxHeight: '250px',
243
212
  overflowY: 'auto',
244
213
  whiteSpace: 'pre-wrap',
214
+ fontSize: 13,
215
+ color: '#454545',
216
+ lineHeight: 'auto',
245
217
  });
246
218
  descriptionC.innerHTML = guidelines;
247
219
  const button = createElement('div', 'button_begin_or', styles.buttonWidgetStyle, 'Begin Test');
@@ -261,15 +233,21 @@ export default class UserTestManager {
261
233
  content.removeChild(button);
262
234
  };
263
235
  button.onclick = () => {
236
+ var _a, _b, _c;
264
237
  toggleDescriptionVisibility();
265
238
  if (this.test) {
266
- if (this.durations.tasks.findIndex((t) => this.test && t.taskId === this.test.tasks[0].task_id) === -1) {
267
- this.durations.tasks.push({
239
+ const durations = (_a = this.signalManager) === null || _a === void 0 ? void 0 : _a.getDurations();
240
+ const taskDurationInd = durations
241
+ ? durations.tasks.findIndex((t) => this.test && t.taskId === this.test.tasks[0].task_id)
242
+ : null;
243
+ if (durations && taskDurationInd === -1) {
244
+ durations.tasks.push({
268
245
  taskId: this.test.tasks[0].task_id,
269
246
  started: this.app.timestamp(),
270
247
  });
248
+ (_b = this.signalManager) === null || _b === void 0 ? void 0 : _b.setDurations(durations);
271
249
  }
272
- void this.signalTask(this.test.tasks[0].task_id, 'begin');
250
+ void ((_c = this.signalManager) === null || _c === void 0 ? void 0 : _c.signalTask(this.test.tasks[0].task_id, 'begin'));
273
251
  }
274
252
  this.showTaskSection();
275
253
  content.removeChild(button);
@@ -277,14 +255,20 @@ export default class UserTestManager {
277
255
  return section;
278
256
  }
279
257
  createTasksSection(tasks) {
258
+ this.container.style.fontFamily = `-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"`;
259
+ Object.assign(this.container.style, styles.containerWidgetStyle);
280
260
  const section = createElement('div', 'task_section_or', styles.descriptionWidgetStyle);
281
261
  const titleContainer = createElement('div', 'description_t_title_or', styles.sectionTitleStyle);
282
- const title = createElement('div', 'title', {}, 'Tasks');
262
+ const title = createElement('div', 'title', {
263
+ fontSize: '13px',
264
+ fontWeight: '500',
265
+ lineHeight: 'auto',
266
+ }, 'Tasks');
283
267
  const icon = createElement('div', 'icon', styles.symbolIcon, '-');
284
268
  const content = createElement('div', 'content', styles.contentStyle);
285
269
  const pagination = createElement('div', 'pagination', styles.paginationStyle);
286
- const leftArrow = createElement('span', 'leftArrow', {}, '<');
287
- const rightArrow = createElement('span', 'rightArrow', {}, '>');
270
+ // const leftArrow = createElement('span', 'leftArrow', {}, '<')
271
+ // const rightArrow = createElement('span', 'rightArrow', {}, '>')
288
272
  const taskCard = createElement('div', 'taskCard', styles.taskDescriptionCard);
289
273
  const taskText = createElement('div', 'taskText', styles.taskTextStyle);
290
274
  const taskDescription = createElement('div', 'taskDescription', styles.taskDescriptionStyle);
@@ -296,8 +280,8 @@ export default class UserTestManager {
296
280
  });
297
281
  const inputContainer = createElement('div', 'inputArea', styles.taskDescriptionCard);
298
282
  inputContainer.append(inputTitle, inputArea);
299
- const closePanelButton = createElement('div', 'closePanelButton', styles.taskButtonStyle, 'Collapse panel');
300
- const nextButton = createElement('div', 'nextButton', styles.taskButtonBorderedStyle, 'Done, next');
283
+ const closePanelButton = createElement('div', 'closePanelButton', styles.taskButtonStyle, 'Collapse Panel');
284
+ const nextButton = createElement('div', 'nextButton', styles.taskButtonBorderedStyle, 'Done, Next');
301
285
  titleContainer.append(title, icon);
302
286
  taskCard.append(taskText, taskDescription);
303
287
  taskButtons.append(closePanelButton, nextButton);
@@ -314,13 +298,23 @@ export default class UserTestManager {
314
298
  inputContainer.style.display = 'none';
315
299
  }
316
300
  };
317
- pagination.appendChild(leftArrow);
301
+ // pagination.appendChild(leftArrow)
318
302
  tasks.forEach((_, index) => {
319
- const pageNumber = createElement('span', `or_task_${index}`, {}, (index + 1).toString());
303
+ const pageNumber = createElement('span', `or_task_${index}`, {
304
+ outline: '1px solid #efefef',
305
+ fontSize: '13px',
306
+ height: '24px',
307
+ width: '24px',
308
+ display: 'flex',
309
+ flexDirection: 'column',
310
+ alignItems: 'center',
311
+ justifyContent: 'center',
312
+ borderRadius: '6.25em',
313
+ }, (index + 1).toString());
320
314
  pageNumber.id = `or_task_${index}`;
321
315
  pagination.append(pageNumber);
322
316
  });
323
- pagination.appendChild(rightArrow);
317
+ // pagination.appendChild(rightArrow)
324
318
  const toggleTasksVisibility = () => {
325
319
  this.widgetTasksVisible = !this.widgetTasksVisible;
326
320
  icon.textContent = this.widgetTasksVisible ? '-' : '+';
@@ -355,19 +349,23 @@ export default class UserTestManager {
355
349
  titleContainer.onclick = toggleTasksVisibility;
356
350
  closePanelButton.onclick = this.collapseWidget;
357
351
  nextButton.onclick = () => {
352
+ var _a, _b, _c, _d;
358
353
  const textAnswer = tasks[this.currentTaskIndex].allow_typing ? inputArea.value : undefined;
359
354
  inputArea.value = '';
360
- void this.signalTask(tasks[this.currentTaskIndex].task_id, 'done', textAnswer);
355
+ void ((_a = this.signalManager) === null || _a === void 0 ? void 0 : _a.signalTask(tasks[this.currentTaskIndex].task_id, 'done', textAnswer));
361
356
  if (this.currentTaskIndex < tasks.length - 1) {
362
357
  this.currentTaskIndex++;
363
358
  updateTaskContent();
364
- if (this.durations.tasks.findIndex((t) => t.taskId === tasks[this.currentTaskIndex].task_id) === -1) {
365
- this.durations.tasks.push({
359
+ const durations = (_b = this.signalManager) === null || _b === void 0 ? void 0 : _b.getDurations();
360
+ if (durations &&
361
+ durations.tasks.findIndex((t) => t.taskId === tasks[this.currentTaskIndex].task_id) === -1) {
362
+ durations.tasks.push({
366
363
  taskId: tasks[this.currentTaskIndex].task_id,
367
364
  started: this.app.timestamp(),
368
365
  });
366
+ (_c = this.signalManager) === null || _c === void 0 ? void 0 : _c.setDurations(durations);
369
367
  }
370
- void this.signalTask(tasks[this.currentTaskIndex].task_id, 'begin');
368
+ void ((_d = this.signalManager) === null || _d === void 0 ? void 0 : _d.signalTask(tasks[this.currentTaskIndex].task_id, 'begin'));
371
369
  highlightActive();
372
370
  }
373
371
  else {
@@ -386,33 +384,48 @@ export default class UserTestManager {
386
384
  return section;
387
385
  }
388
386
  showEndSection() {
389
- var _a, _b, _c, _d, _e, _f;
387
+ var _a, _b, _c, _d, _e;
390
388
  let isLoading = true;
391
- void this.signalTest('done');
389
+ void ((_a = this.signalManager) === null || _a === void 0 ? void 0 : _a.signalTest('done'));
392
390
  const section = createElement('div', 'end_section_or', styles.endSectionStyle);
393
391
  const title = createElement('div', 'end_title_or', {
394
392
  fontSize: '1.25rem',
395
393
  fontWeight: '500',
396
- }, ((_a = this.test) === null || _a === void 0 ? void 0 : _a.reqMic) || ((_b = this.test) === null || _b === void 0 ? void 0 : _b.reqCamera) ? 'Uploading test recording...' : 'Thank you! 👍');
397
- const description = createElement('div', 'end_description_or', {}, (_d = (_c = this.test) === null || _c === void 0 ? void 0 : _c.conclusion) !== null && _d !== void 0 ? _d : 'Thank you for participating in our usability test. Your feedback has been captured and will be used to enhance our website. \n' +
394
+ }, 'Thank you! 👍');
395
+ const description = createElement('div', 'end_description_or', {}, (_c = (_b = this.test) === null || _b === void 0 ? void 0 : _b.conclusion) !== null && _c !== void 0 ? _c : 'Thank you for participating in our usability test. Your feedback has been captured and will be used to enhance our website. \n' +
398
396
  '\n' +
399
397
  'We appreciate your time and valuable input.');
400
- const button = createElement('div', 'end_button_or', styles.buttonWidgetStyle, 'Uploading session...');
401
- if (((_e = this.test) === null || _e === void 0 ? void 0 : _e.reqMic) || ((_f = this.test) === null || _f === void 0 ? void 0 : _f.reqCamera)) {
402
- void this.userRecorder.sendToAPI().then(() => {
403
- title.textContent = 'Thank you! 👍';
398
+ const button = createElement('div', 'end_button_or', styles.buttonWidgetStyle, 'Submitting Feedback');
399
+ const spinner = createSpinner();
400
+ button.appendChild(spinner);
401
+ if (((_d = this.test) === null || _d === void 0 ? void 0 : _d.reqMic) || ((_e = this.test) === null || _e === void 0 ? void 0 : _e.reqCamera)) {
402
+ void this.userRecorder
403
+ .sendToAPI()
404
+ .then(() => {
405
+ button.removeChild(spinner);
406
+ button.textContent = 'End Session';
407
+ isLoading = false;
408
+ })
409
+ .catch((err) => {
410
+ console.error(err);
411
+ button.removeChild(spinner);
404
412
  button.textContent = 'End Session';
405
413
  isLoading = false;
406
414
  });
407
415
  }
416
+ else {
417
+ button.removeChild(spinner);
418
+ button.textContent = 'End Session';
419
+ isLoading = false;
420
+ }
408
421
  if (this.taskSection) {
409
422
  this.container.removeChild(this.taskSection);
410
423
  }
411
424
  if (this.descriptionSection) {
412
425
  this.container.removeChild(this.descriptionSection);
413
426
  }
414
- if (this.stopButton) {
415
- this.container.removeChild(this.stopButton);
427
+ if (this.stopButton && this.stopButtonContainer) {
428
+ this.container.removeChild(this.stopButtonContainer);
416
429
  }
417
430
  button.onclick = () => {
418
431
  if (isLoading)
@@ -425,49 +438,3 @@ export default class UserTestManager {
425
438
  this.container.append(section);
426
439
  }
427
440
  }
428
- function generateGrid() {
429
- const grid = document.createElement('div');
430
- grid.className = 'grid';
431
- for (let i = 0; i < 16; i++) {
432
- const cell = document.createElement('div');
433
- Object.assign(cell.style, {
434
- width: '2px',
435
- height: '2px',
436
- borderRadius: '10px',
437
- background: 'white',
438
- });
439
- cell.className = 'cell';
440
- grid.appendChild(cell);
441
- }
442
- Object.assign(grid.style, {
443
- display: 'grid',
444
- gridTemplateColumns: 'repeat(4, 1fr)',
445
- gridTemplateRows: 'repeat(4, 1fr)',
446
- gap: '2px',
447
- cursor: 'grab',
448
- });
449
- return grid;
450
- }
451
- function generateChevron() {
452
- const triangle = document.createElement('div');
453
- Object.assign(triangle.style, {
454
- width: '0',
455
- height: '0',
456
- borderLeft: '7px solid transparent',
457
- borderRight: '7px solid transparent',
458
- borderBottom: '7px solid white',
459
- });
460
- const container = document.createElement('div');
461
- container.appendChild(triangle);
462
- Object.assign(container.style, {
463
- display: 'flex',
464
- alignItems: 'center',
465
- justifyContent: 'center',
466
- width: '16px',
467
- height: '16px',
468
- cursor: 'pointer',
469
- marginLeft: 'auto',
470
- transform: 'rotate(180deg)',
471
- });
472
- return container;
473
- }
@@ -9,6 +9,7 @@ export declare const bgStyle: {
9
9
  alignItems: string;
10
10
  justifyContent: string;
11
11
  zIndex: number;
12
+ fontFamily: string;
12
13
  };
13
14
  export declare const containerStyle: {
14
15
  display: string;
@@ -27,6 +28,7 @@ export declare const containerWidgetStyle: {
27
28
  gap: string;
28
29
  'align-items': string;
29
30
  padding: string;
31
+ fontFamily: string;
30
32
  'border-radius': string;
31
33
  border: string;
32
34
  background: string;
@@ -50,6 +52,7 @@ export declare const descriptionStyle: {
50
52
  fontStyle: string;
51
53
  fontWeight: string;
52
54
  lineHeight: string;
55
+ whiteSpace: string;
53
56
  };
54
57
  export declare const noticeStyle: {
55
58
  color: string;
@@ -93,6 +96,8 @@ export declare const contentStyle: {
93
96
  flexDirection: string;
94
97
  alignItems: string;
95
98
  gap: string;
99
+ fontSize: string;
100
+ lineHeight: string;
96
101
  };
97
102
  export declare const titleWidgetStyle: {
98
103
  padding: string;
@@ -114,17 +119,14 @@ export declare const descriptionWidgetStyle: {
114
119
  boxSizing: string;
115
120
  display: string;
116
121
  width: string;
117
- borderRadius: string;
118
- border: string;
122
+ borderBottom: string;
119
123
  background: string;
120
124
  padding: string;
121
125
  alignSelf: string;
122
126
  color: string;
123
127
  fontFamily: string;
124
- fontSize: string;
125
128
  fontStyle: string;
126
129
  fontWeight: string;
127
- lineHeight: string;
128
130
  };
129
131
  export declare const endSectionStyle: {
130
132
  display: string;
@@ -133,17 +135,14 @@ export declare const endSectionStyle: {
133
135
  gap: string;
134
136
  boxSizing: string;
135
137
  width: string;
136
- borderRadius: string;
137
- border: string;
138
+ borderBottom: string;
138
139
  background: string;
139
140
  padding: string;
140
141
  alignSelf: string;
141
142
  color: string;
142
143
  fontFamily: string;
143
- fontSize: string;
144
144
  fontStyle: string;
145
145
  fontWeight: string;
146
- lineHeight: string;
147
146
  };
148
147
  export declare const symbolIcon: {
149
148
  fontSize: string;
@@ -174,9 +173,12 @@ export declare const buttonWidgetStyle: {
174
173
  };
175
174
  export declare const stopWidgetStyle: {
176
175
  marginTop: string;
176
+ marginBottom: string;
177
177
  cursor: string;
178
178
  display: string;
179
179
  fontWeight: string;
180
+ fontSize: string;
181
+ lineHeight: string;
180
182
  };
181
183
  export declare const paginationStyle: {
182
184
  display: string;
@@ -189,21 +191,27 @@ export declare const paginationStyle: {
189
191
  };
190
192
  export declare const taskNumberActive: {
191
193
  display: string;
192
- padding: string;
193
194
  flexDirection: string;
194
195
  alignItems: string;
196
+ justifyContent: string;
195
197
  borderRadius: string;
196
198
  outline: string;
199
+ fontSize: string;
200
+ height: string;
201
+ width: string;
197
202
  };
198
203
  export declare const taskNumberDone: {
199
204
  display: string;
200
- padding: string;
201
205
  flexDirection: string;
202
206
  alignItems: string;
207
+ justifyContent: string;
203
208
  borderRadius: string;
204
209
  outline: string;
205
210
  boxShadow: string;
206
211
  background: string;
212
+ fontSize: string;
213
+ height: string;
214
+ width: string;
207
215
  };
208
216
  export declare const taskDescriptionCard: {
209
217
  borderRadius: string;
@@ -220,7 +228,8 @@ export declare const taskTextStyle: {
220
228
  fontWeight: string;
221
229
  };
222
230
  export declare const taskDescriptionStyle: {
223
- color: string;
231
+ fontSize: string;
232
+ lineHeight: string;
224
233
  };
225
234
  export declare const taskButtonStyle: {
226
235
  marginRight: string;
@@ -258,3 +267,11 @@ export declare const taskButtonsRow: {
258
267
  width: string;
259
268
  boxSizing: string;
260
269
  };
270
+ export declare const spinnerStyles: {
271
+ border: string;
272
+ width: string;
273
+ height: string;
274
+ borderRadius: string;
275
+ borderLeftColor: string;
276
+ animation: string;
277
+ };