@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.
- package/CHANGELOG.md +4 -0
- package/cjs/app/index.d.ts +4 -0
- package/cjs/app/index.js +28 -4
- package/cjs/index.d.ts +1 -0
- package/cjs/index.js +7 -1
- package/cjs/modules/userTesting/SignalManager.d.ts +29 -0
- package/cjs/modules/userTesting/SignalManager.js +83 -0
- package/cjs/modules/userTesting/index.d.ts +7 -7
- package/cjs/modules/userTesting/index.js +169 -195
- 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 +851 -351
- package/coverage/coverage-final.json +10 -4
- package/coverage/lcov-report/index.html +38 -23
- 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 +196 -28
- 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 +33 -6
- 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/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 +1 -1
- 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 +1 -1
- 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 +361 -0
- package/coverage/lcov-report/main/modules/userTesting/dnd.ts.html +10 -22
- package/coverage/lcov-report/main/modules/userTesting/index.html +61 -31
- package/coverage/lcov-report/main/modules/userTesting/index.ts.html +809 -113
- package/coverage/lcov-report/main/modules/userTesting/recorder.ts.html +136 -67
- package/coverage/lcov-report/main/modules/userTesting/styles.ts.html +159 -87
- package/coverage/lcov-report/main/modules/userTesting/utils.ts.html +361 -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 +1 -1
- package/coverage/lcov-report/webworker/index.ts.html +1 -1
- package/coverage/lcov.info +1535 -653
- package/lib/app/index.d.ts +4 -0
- package/lib/app/index.js +28 -4
- package/lib/index.d.ts +1 -0
- package/lib/index.js +7 -1
- package/lib/modules/userTesting/SignalManager.d.ts +29 -0
- package/lib/modules/userTesting/SignalManager.js +80 -0
- package/lib/modules/userTesting/index.d.ts +7 -7
- package/lib/modules/userTesting/index.js +141 -167
- 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 +2 -2
package/CHANGELOG.md
CHANGED
package/cjs/app/index.d.ts
CHANGED
|
@@ -54,6 +54,7 @@ type AppOptions = {
|
|
|
54
54
|
sessionStorage: Storage | null;
|
|
55
55
|
forceSingleTab?: boolean;
|
|
56
56
|
disableStringDict?: boolean;
|
|
57
|
+
assistSocketHost?: string;
|
|
57
58
|
onStart?: StartCallback;
|
|
58
59
|
network?: NetworkOptions;
|
|
59
60
|
} & WebworkerOptions & SessOptions;
|
|
@@ -126,6 +127,9 @@ export default class App {
|
|
|
126
127
|
active(): boolean;
|
|
127
128
|
resetNextPageSession(flag: boolean): void;
|
|
128
129
|
private _start;
|
|
130
|
+
onUxtCb: never[];
|
|
131
|
+
addOnUxtCb(cb: (id: number) => void): void;
|
|
132
|
+
getUxtId(): number | null;
|
|
129
133
|
/**
|
|
130
134
|
* basically we ask other tabs during constructor
|
|
131
135
|
* and here we just apply 10ms delay just in case
|
package/cjs/app/index.js
CHANGED
|
@@ -42,13 +42,14 @@ class App {
|
|
|
42
42
|
this.stopCallbacks = [];
|
|
43
43
|
this.commitCallbacks = [];
|
|
44
44
|
this.activityState = ActivityState.NotActive;
|
|
45
|
-
this.version = '11.0.
|
|
45
|
+
this.version = '11.0.1'; // TODO: version compatability check inside each plugin.
|
|
46
46
|
this.compressionThreshold = 24 * 1000;
|
|
47
47
|
this.restartAttempts = 0;
|
|
48
48
|
this.bc = null;
|
|
49
49
|
this.canvasRecorder = null;
|
|
50
50
|
this._usingOldFetchPlugin = false;
|
|
51
51
|
this.delay = 0;
|
|
52
|
+
this.onUxtCb = [];
|
|
52
53
|
// if (options.onStart !== undefined) {
|
|
53
54
|
// deprecationWarn("'onStart' option", "tracker.start().then(/* handle session info */)")
|
|
54
55
|
// } ?? maybe onStart is good
|
|
@@ -72,6 +73,7 @@ class App {
|
|
|
72
73
|
sessionStorage: null,
|
|
73
74
|
disableStringDict: false,
|
|
74
75
|
forceSingleTab: false,
|
|
76
|
+
assistSocketHost: '',
|
|
75
77
|
}, options);
|
|
76
78
|
if (!this.options.forceSingleTab && globalThis && 'BroadcastChannel' in globalThis) {
|
|
77
79
|
const host = location.hostname.split('.').slice(-2).join('_');
|
|
@@ -200,7 +202,6 @@ class App {
|
|
|
200
202
|
}
|
|
201
203
|
};
|
|
202
204
|
}
|
|
203
|
-
this.uxtManager = new index_js_1.default(this, uxtStorageKey);
|
|
204
205
|
}
|
|
205
206
|
_debug(context, e) {
|
|
206
207
|
if (this.options.__debug_report_edp !== null) {
|
|
@@ -512,6 +513,9 @@ class App {
|
|
|
512
513
|
this.options.onStart(onStartInfo);
|
|
513
514
|
}
|
|
514
515
|
this.restartAttempts = 0;
|
|
516
|
+
this.uxtManager = this.uxtManager
|
|
517
|
+
? this.uxtManager
|
|
518
|
+
: new index_js_1.default(this, uxtStorageKey);
|
|
515
519
|
let uxtId;
|
|
516
520
|
const savedUxtTag = this.localStorage.getItem(uxtStorageKey);
|
|
517
521
|
if (savedUxtTag) {
|
|
@@ -524,8 +528,20 @@ class App {
|
|
|
524
528
|
uxtId = qId ? parseInt(qId, 10) : undefined;
|
|
525
529
|
}
|
|
526
530
|
}
|
|
527
|
-
if (uxtId)
|
|
528
|
-
this.uxtManager.
|
|
531
|
+
if (uxtId) {
|
|
532
|
+
if (!this.uxtManager.isActive) {
|
|
533
|
+
// eslint-disable-next-line
|
|
534
|
+
this.uxtManager.getTest(uxtId, token, Boolean(savedUxtTag)).then((id) => {
|
|
535
|
+
if (id) {
|
|
536
|
+
this.onUxtCb.forEach((cb) => cb(id));
|
|
537
|
+
}
|
|
538
|
+
});
|
|
539
|
+
}
|
|
540
|
+
else {
|
|
541
|
+
// @ts-ignore
|
|
542
|
+
this.onUxtCb.forEach((cb) => cb(uxtId));
|
|
543
|
+
}
|
|
544
|
+
}
|
|
529
545
|
return SuccessfulStart(onStartInfo);
|
|
530
546
|
})
|
|
531
547
|
.catch((reason) => {
|
|
@@ -539,6 +555,14 @@ class App {
|
|
|
539
555
|
return UnsuccessfulStart(START_ERROR);
|
|
540
556
|
});
|
|
541
557
|
}
|
|
558
|
+
addOnUxtCb(cb) {
|
|
559
|
+
// @ts-ignore
|
|
560
|
+
this.onUxtCb.push(cb);
|
|
561
|
+
}
|
|
562
|
+
getUxtId() {
|
|
563
|
+
var _a;
|
|
564
|
+
return (_a = this.uxtManager) === null || _a === void 0 ? void 0 : _a.getTestId();
|
|
565
|
+
}
|
|
542
566
|
/**
|
|
543
567
|
* basically we ask other tabs during constructor
|
|
544
568
|
* and here we just apply 10ms delay just in case
|
package/cjs/index.d.ts
CHANGED
|
@@ -47,6 +47,7 @@ export default class API {
|
|
|
47
47
|
getSessionToken(): string | null | undefined;
|
|
48
48
|
getSessionID(): string | null | undefined;
|
|
49
49
|
getTabId(): string | null;
|
|
50
|
+
getUxId(): number | null;
|
|
50
51
|
sessionID(): string | null | undefined;
|
|
51
52
|
getSessionURL(options?: {
|
|
52
53
|
withCurrentTime?: boolean;
|
package/cjs/index.js
CHANGED
|
@@ -162,7 +162,7 @@ class API {
|
|
|
162
162
|
// no-cors issue only with text/plain or not-set Content-Type
|
|
163
163
|
// req.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
|
|
164
164
|
req.send(JSON.stringify({
|
|
165
|
-
trackerVersion: '11.0.
|
|
165
|
+
trackerVersion: '11.0.1',
|
|
166
166
|
projectKey: options.projectKey,
|
|
167
167
|
doNotTrack,
|
|
168
168
|
// TODO: add precise reason (an exact API missing)
|
|
@@ -238,6 +238,12 @@ class API {
|
|
|
238
238
|
}
|
|
239
239
|
return this.app.getTabId();
|
|
240
240
|
}
|
|
241
|
+
getUxId() {
|
|
242
|
+
if (this.app === null) {
|
|
243
|
+
return null;
|
|
244
|
+
}
|
|
245
|
+
return this.app.getUxtId();
|
|
246
|
+
}
|
|
241
247
|
sessionID() {
|
|
242
248
|
(0, utils_js_1.deprecationWarn)("'sessionID' method", "'getSessionID' method", '/');
|
|
243
249
|
return this.getSessionID();
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export default class SignalManager {
|
|
2
|
+
private readonly ingestPoint;
|
|
3
|
+
private readonly getTimestamp;
|
|
4
|
+
private readonly token;
|
|
5
|
+
private readonly testId;
|
|
6
|
+
private readonly storageKey;
|
|
7
|
+
private readonly setStorageKey;
|
|
8
|
+
private readonly removeStorageKey;
|
|
9
|
+
private readonly getStorageKey;
|
|
10
|
+
private readonly getSessionId;
|
|
11
|
+
private readonly durations;
|
|
12
|
+
constructor(ingestPoint: string, getTimestamp: () => number, token: string, testId: number, storageKey: string, setStorageKey: (key: string, value: string) => void, removeStorageKey: (key: string) => void, getStorageKey: (key: string) => string | null, getSessionId: () => string | undefined);
|
|
13
|
+
getDurations: () => {
|
|
14
|
+
testStart: number;
|
|
15
|
+
tasks: {
|
|
16
|
+
taskId: number;
|
|
17
|
+
started: number;
|
|
18
|
+
}[];
|
|
19
|
+
};
|
|
20
|
+
setDurations: (durations: {
|
|
21
|
+
testStart: number;
|
|
22
|
+
tasks: {
|
|
23
|
+
taskId: number;
|
|
24
|
+
started: number;
|
|
25
|
+
}[];
|
|
26
|
+
}) => void;
|
|
27
|
+
signalTask: (taskId: number, status: 'begin' | 'done' | 'skipped', taskAnswer?: string) => void | Promise<Response>;
|
|
28
|
+
signalTest: (status: 'begin' | 'done' | 'skipped') => Promise<Response>;
|
|
29
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const utils_js_1 = require("./utils.js");
|
|
4
|
+
class SignalManager {
|
|
5
|
+
constructor(ingestPoint, getTimestamp, token, testId, storageKey, setStorageKey, removeStorageKey, getStorageKey, getSessionId) {
|
|
6
|
+
this.ingestPoint = ingestPoint;
|
|
7
|
+
this.getTimestamp = getTimestamp;
|
|
8
|
+
this.token = token;
|
|
9
|
+
this.testId = testId;
|
|
10
|
+
this.storageKey = storageKey;
|
|
11
|
+
this.setStorageKey = setStorageKey;
|
|
12
|
+
this.removeStorageKey = removeStorageKey;
|
|
13
|
+
this.getStorageKey = getStorageKey;
|
|
14
|
+
this.getSessionId = getSessionId;
|
|
15
|
+
this.durations = {
|
|
16
|
+
testStart: 0,
|
|
17
|
+
tasks: [],
|
|
18
|
+
};
|
|
19
|
+
this.getDurations = () => {
|
|
20
|
+
return this.durations;
|
|
21
|
+
};
|
|
22
|
+
this.setDurations = (durations) => {
|
|
23
|
+
this.durations.testStart = durations.testStart;
|
|
24
|
+
this.durations.tasks = durations.tasks;
|
|
25
|
+
};
|
|
26
|
+
this.signalTask = (taskId, status, taskAnswer) => {
|
|
27
|
+
if (!taskId)
|
|
28
|
+
return console.error('User Testing: No Task ID Given');
|
|
29
|
+
const taskStart = this.durations.tasks.find((t) => t.taskId === taskId);
|
|
30
|
+
const timestamp = this.getTimestamp();
|
|
31
|
+
const duration = taskStart ? timestamp - taskStart.started : 0;
|
|
32
|
+
return fetch(`${this.ingestPoint}/v1/web/uxt/signals/task`, {
|
|
33
|
+
method: 'POST',
|
|
34
|
+
headers: {
|
|
35
|
+
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
|
|
36
|
+
Authorization: `Bearer ${this.token}`,
|
|
37
|
+
},
|
|
38
|
+
body: JSON.stringify({
|
|
39
|
+
testId: this.testId,
|
|
40
|
+
taskId,
|
|
41
|
+
status,
|
|
42
|
+
duration,
|
|
43
|
+
timestamp,
|
|
44
|
+
taskAnswer,
|
|
45
|
+
}),
|
|
46
|
+
});
|
|
47
|
+
};
|
|
48
|
+
this.signalTest = (status) => {
|
|
49
|
+
const timestamp = this.getTimestamp();
|
|
50
|
+
if (status === 'begin' && this.testId) {
|
|
51
|
+
const sessionId = this.getSessionId();
|
|
52
|
+
this.setStorageKey(utils_js_1.SESSION_ID, sessionId);
|
|
53
|
+
this.setStorageKey(this.storageKey, this.testId.toString());
|
|
54
|
+
this.setStorageKey(utils_js_1.TEST_START, timestamp.toString());
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
this.removeStorageKey(this.storageKey);
|
|
58
|
+
this.removeStorageKey(utils_js_1.TASK_IND);
|
|
59
|
+
this.removeStorageKey(utils_js_1.TEST_START);
|
|
60
|
+
}
|
|
61
|
+
const start = this.durations.testStart || timestamp;
|
|
62
|
+
const duration = timestamp - start;
|
|
63
|
+
return fetch(`${this.ingestPoint}/v1/web/uxt/signals/test`, {
|
|
64
|
+
method: 'POST',
|
|
65
|
+
headers: {
|
|
66
|
+
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
|
|
67
|
+
Authorization: `Bearer ${this.token}`,
|
|
68
|
+
},
|
|
69
|
+
body: JSON.stringify({
|
|
70
|
+
testId: this.testId,
|
|
71
|
+
status,
|
|
72
|
+
duration,
|
|
73
|
+
timestamp,
|
|
74
|
+
}),
|
|
75
|
+
});
|
|
76
|
+
};
|
|
77
|
+
const possibleStart = this.getStorageKey(utils_js_1.TEST_START);
|
|
78
|
+
if (possibleStart) {
|
|
79
|
+
this.durations.testStart = parseInt(possibleStart, 10);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
exports.default = SignalManager;
|
|
@@ -8,24 +8,24 @@ export default class UserTestManager {
|
|
|
8
8
|
private widgetGuidelinesVisible;
|
|
9
9
|
private widgetTasksVisible;
|
|
10
10
|
private widgetVisible;
|
|
11
|
+
isActive: boolean;
|
|
11
12
|
private descriptionSection;
|
|
12
13
|
private taskSection;
|
|
13
14
|
private endSection;
|
|
14
15
|
private stopButton;
|
|
16
|
+
private stopButtonContainer;
|
|
15
17
|
private test;
|
|
16
18
|
private testId;
|
|
17
|
-
private
|
|
18
|
-
private readonly durations;
|
|
19
|
+
private signalManager;
|
|
19
20
|
constructor(app: App, storageKey: string);
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
getTest: (id: number, token: string, inProgress?: boolean) => void;
|
|
21
|
+
getTestId(): number | null;
|
|
22
|
+
getTest: (id: number, token: string, inProgress?: boolean) => Promise<number | void>;
|
|
23
23
|
hideTaskSection: () => boolean;
|
|
24
24
|
showTaskSection: () => boolean;
|
|
25
25
|
collapseWidget: () => boolean;
|
|
26
26
|
removeGreeting: () => boolean;
|
|
27
27
|
createGreeting(title: string, micRequired: boolean, cameraRequired: boolean): void;
|
|
28
|
-
showWidget(
|
|
28
|
+
showWidget(guidelines: string, tasks: {
|
|
29
29
|
title: string;
|
|
30
30
|
description: string;
|
|
31
31
|
task_id: number;
|
|
@@ -33,7 +33,7 @@ export default class UserTestManager {
|
|
|
33
33
|
}[], inProgress?: boolean): void;
|
|
34
34
|
createTitleSection(): HTMLElement;
|
|
35
35
|
toggleDescriptionVisibility: () => void;
|
|
36
|
-
createDescriptionSection(
|
|
36
|
+
createDescriptionSection(guidelines: string): HTMLElement;
|
|
37
37
|
currentTaskIndex: number;
|
|
38
38
|
createTasksSection(tasks: {
|
|
39
39
|
title: string;
|