@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.
- package/CHANGELOG.md +4 -0
- package/cjs/app/index.d.ts +3 -0
- package/cjs/app/index.js +27 -4
- package/cjs/index.d.ts +1 -0
- package/cjs/index.js +7 -1
- package/cjs/modules/Network/fetchProxy.js +4 -2
- package/cjs/modules/userTesting/SignalManager.d.ts +29 -0
- package/cjs/modules/userTesting/SignalManager.js +83 -0
- package/cjs/modules/userTesting/index.d.ts +5 -5
- package/cjs/modules/userTesting/index.js +156 -189
- package/cjs/modules/userTesting/styles.d.ts +28 -11
- package/cjs/modules/userTesting/styles.js +51 -29
- package/cjs/modules/userTesting/utils.d.ts +9 -0
- package/cjs/modules/userTesting/utils.js +87 -0
- package/coverage/clover.xml +1331 -562
- package/coverage/coverage-final.json +13 -6
- package/coverage/lcov-report/index.html +49 -34
- package/coverage/lcov-report/main/app/canvas.ts.html +1 -1
- package/coverage/lcov-report/main/app/guards.ts.html +42 -42
- package/coverage/lcov-report/main/app/index.html +24 -24
- package/coverage/lcov-report/main/app/index.ts.html +1046 -56
- package/coverage/lcov-report/main/app/logger.ts.html +1 -1
- package/coverage/lcov-report/main/app/messages.gen.ts.html +1 -1
- package/coverage/lcov-report/main/app/nodes.ts.html +1 -1
- package/coverage/lcov-report/main/app/observer/iframe_observer.ts.html +1 -1
- package/coverage/lcov-report/main/app/observer/iframe_offsets.ts.html +1 -1
- package/coverage/lcov-report/main/app/observer/index.html +1 -1
- package/coverage/lcov-report/main/app/observer/shadow_root_observer.ts.html +1 -1
- package/coverage/lcov-report/main/app/observer/top_observer.ts.html +1 -1
- package/coverage/lcov-report/main/app/sanitizer.ts.html +1 -1
- package/coverage/lcov-report/main/app/session.ts.html +1 -1
- package/coverage/lcov-report/main/app/ticker.ts.html +1 -1
- package/coverage/lcov-report/main/index.html +11 -11
- package/coverage/lcov-report/main/index.ts.html +274 -100
- package/coverage/lcov-report/main/modules/Network/beaconProxy.ts.html +1 -1
- package/coverage/lcov-report/main/modules/Network/fetchProxy.ts.html +1 -1
- package/coverage/lcov-report/main/modules/Network/index.html +1 -1
- package/coverage/lcov-report/main/modules/Network/index.ts.html +1 -1
- package/coverage/lcov-report/main/modules/Network/networkMessage.ts.html +1 -1
- package/coverage/lcov-report/main/modules/Network/utils.ts.html +1 -1
- package/coverage/lcov-report/main/modules/Network/xhrProxy.ts.html +1 -1
- package/coverage/lcov-report/main/modules/attributeSender.ts.html +1 -1
- package/coverage/lcov-report/main/modules/axiosSpy.ts.html +1 -1
- package/coverage/lcov-report/main/modules/conditionsManager.ts.html +799 -0
- package/coverage/lcov-report/main/modules/connection.ts.html +1 -1
- package/coverage/lcov-report/main/modules/console.ts.html +1 -1
- package/coverage/lcov-report/main/modules/constructedStyleSheets.ts.html +1 -1
- package/coverage/lcov-report/main/modules/cssrules.ts.html +1 -1
- package/coverage/lcov-report/main/modules/exception.ts.html +1 -1
- package/coverage/lcov-report/main/modules/featureFlags.ts.html +10 -7
- package/coverage/lcov-report/main/modules/focus.ts.html +1 -1
- package/coverage/lcov-report/main/modules/fonts.ts.html +1 -1
- package/coverage/lcov-report/main/modules/img.ts.html +1 -1
- package/coverage/lcov-report/main/modules/index.html +27 -12
- package/coverage/lcov-report/main/modules/input.ts.html +1 -1
- package/coverage/lcov-report/main/modules/mouse.ts.html +1 -1
- package/coverage/lcov-report/main/modules/network.ts.html +1 -1
- package/coverage/lcov-report/main/modules/performance.ts.html +1 -1
- package/coverage/lcov-report/main/modules/scroll.ts.html +1 -1
- package/coverage/lcov-report/main/modules/selection.ts.html +1 -1
- package/coverage/lcov-report/main/modules/tabs.ts.html +1 -1
- package/coverage/lcov-report/main/modules/timing.ts.html +1 -1
- package/coverage/lcov-report/main/modules/userTesting/SignalManager.ts.html +370 -0
- package/coverage/lcov-report/main/modules/userTesting/dnd.ts.html +10 -22
- package/coverage/lcov-report/main/modules/userTesting/index.html +57 -27
- package/coverage/lcov-report/main/modules/userTesting/index.ts.html +814 -115
- package/coverage/lcov-report/main/modules/userTesting/recorder.ts.html +136 -67
- package/coverage/lcov-report/main/modules/userTesting/styles.ts.html +111 -39
- package/coverage/lcov-report/main/modules/userTesting/utils.ts.html +364 -0
- package/coverage/lcov-report/main/modules/viewport.ts.html +1 -1
- package/coverage/lcov-report/main/utils.ts.html +48 -6
- package/coverage/lcov-report/webworker/BatchWriter.ts.html +1 -1
- package/coverage/lcov-report/webworker/MessageEncoder.gen.ts.html +1 -1
- package/coverage/lcov-report/webworker/PrimitiveEncoder.ts.html +1 -1
- package/coverage/lcov-report/webworker/QueueSender.ts.html +1 -1
- package/coverage/lcov-report/webworker/index.html +5 -5
- package/coverage/lcov-report/webworker/index.ts.html +15 -9
- package/coverage/lcov.info +2306 -900
- package/lib/app/index.d.ts +3 -0
- package/lib/app/index.js +27 -4
- package/lib/index.d.ts +1 -0
- package/lib/index.js +7 -1
- package/lib/modules/Network/fetchProxy.js +4 -2
- package/lib/modules/userTesting/SignalManager.d.ts +29 -0
- package/lib/modules/userTesting/SignalManager.js +80 -0
- package/lib/modules/userTesting/index.d.ts +5 -5
- package/lib/modules/userTesting/index.js +128 -161
- package/lib/modules/userTesting/styles.d.ts +28 -11
- package/lib/modules/userTesting/styles.js +50 -28
- package/lib/modules/userTesting/utils.d.ts +9 -0
- package/lib/modules/userTesting/utils.js +79 -0
- 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
|
-
|
|
5
|
-
|
|
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.
|
|
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(
|
|
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(
|
|
125
|
-
this.app.localStorage.removeItem(
|
|
126
|
-
this.app.localStorage.removeItem(
|
|
127
|
-
this.app.localStorage.removeItem(
|
|
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(
|
|
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,
|
|
138
|
-
|
|
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
|
-
|
|
155
|
-
|
|
156
|
-
|
|
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,
|
|
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
|
-
|
|
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', {
|
|
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
|
-
|
|
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', {
|
|
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
|
-
|
|
267
|
-
|
|
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', {
|
|
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
|
|
300
|
-
const nextButton = createElement('div', 'nextButton', styles.taskButtonBorderedStyle, 'Done,
|
|
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}`, {
|
|
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
|
-
|
|
365
|
-
|
|
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
|
|
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
|
-
},
|
|
397
|
-
const description = createElement('div', 'end_description_or', {}, (
|
|
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, '
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
+
};
|