@openreplay/tracker 11.0.0-beta.1 → 11.0.1

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