@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
package/lib/app/index.d.ts
CHANGED
|
@@ -127,6 +127,9 @@ export default class App {
|
|
|
127
127
|
active(): boolean;
|
|
128
128
|
resetNextPageSession(flag: boolean): void;
|
|
129
129
|
private _start;
|
|
130
|
+
onUxtCb: never[];
|
|
131
|
+
addOnUxtCb(cb: (id: number) => void): void;
|
|
132
|
+
getUxtId(): number | null;
|
|
130
133
|
/**
|
|
131
134
|
* basically we ask other tabs during constructor
|
|
132
135
|
* and here we just apply 10ms delay just in case
|
package/lib/app/index.js
CHANGED
|
@@ -39,13 +39,14 @@ export default class App {
|
|
|
39
39
|
this.stopCallbacks = [];
|
|
40
40
|
this.commitCallbacks = [];
|
|
41
41
|
this.activityState = ActivityState.NotActive;
|
|
42
|
-
this.version = '11.0.
|
|
42
|
+
this.version = '11.0.2'; // TODO: version compatability check inside each plugin.
|
|
43
43
|
this.compressionThreshold = 24 * 1000;
|
|
44
44
|
this.restartAttempts = 0;
|
|
45
45
|
this.bc = null;
|
|
46
46
|
this.canvasRecorder = null;
|
|
47
47
|
this._usingOldFetchPlugin = false;
|
|
48
48
|
this.delay = 0;
|
|
49
|
+
this.onUxtCb = [];
|
|
49
50
|
// if (options.onStart !== undefined) {
|
|
50
51
|
// deprecationWarn("'onStart' option", "tracker.start().then(/* handle session info */)")
|
|
51
52
|
// } ?? maybe onStart is good
|
|
@@ -198,7 +199,6 @@ export default class App {
|
|
|
198
199
|
}
|
|
199
200
|
};
|
|
200
201
|
}
|
|
201
|
-
this.uxtManager = new UserTestManager(this, uxtStorageKey);
|
|
202
202
|
}
|
|
203
203
|
_debug(context, e) {
|
|
204
204
|
if (this.options.__debug_report_edp !== null) {
|
|
@@ -510,6 +510,9 @@ export default class App {
|
|
|
510
510
|
this.options.onStart(onStartInfo);
|
|
511
511
|
}
|
|
512
512
|
this.restartAttempts = 0;
|
|
513
|
+
this.uxtManager = this.uxtManager
|
|
514
|
+
? this.uxtManager
|
|
515
|
+
: new UserTestManager(this, uxtStorageKey);
|
|
513
516
|
let uxtId;
|
|
514
517
|
const savedUxtTag = this.localStorage.getItem(uxtStorageKey);
|
|
515
518
|
if (savedUxtTag) {
|
|
@@ -522,8 +525,20 @@ export default class App {
|
|
|
522
525
|
uxtId = qId ? parseInt(qId, 10) : undefined;
|
|
523
526
|
}
|
|
524
527
|
}
|
|
525
|
-
if (uxtId)
|
|
526
|
-
this.uxtManager.
|
|
528
|
+
if (uxtId) {
|
|
529
|
+
if (!this.uxtManager.isActive) {
|
|
530
|
+
// eslint-disable-next-line
|
|
531
|
+
this.uxtManager.getTest(uxtId, token, Boolean(savedUxtTag)).then((id) => {
|
|
532
|
+
if (id) {
|
|
533
|
+
this.onUxtCb.forEach((cb) => cb(id));
|
|
534
|
+
}
|
|
535
|
+
});
|
|
536
|
+
}
|
|
537
|
+
else {
|
|
538
|
+
// @ts-ignore
|
|
539
|
+
this.onUxtCb.forEach((cb) => cb(uxtId));
|
|
540
|
+
}
|
|
541
|
+
}
|
|
527
542
|
return SuccessfulStart(onStartInfo);
|
|
528
543
|
})
|
|
529
544
|
.catch((reason) => {
|
|
@@ -537,6 +552,14 @@ export default class App {
|
|
|
537
552
|
return UnsuccessfulStart(START_ERROR);
|
|
538
553
|
});
|
|
539
554
|
}
|
|
555
|
+
addOnUxtCb(cb) {
|
|
556
|
+
// @ts-ignore
|
|
557
|
+
this.onUxtCb.push(cb);
|
|
558
|
+
}
|
|
559
|
+
getUxtId() {
|
|
560
|
+
var _a;
|
|
561
|
+
return (_a = this.uxtManager) === null || _a === void 0 ? void 0 : _a.getTestId();
|
|
562
|
+
}
|
|
540
563
|
/**
|
|
541
564
|
* basically we ask other tabs during constructor
|
|
542
565
|
* and here we just apply 10ms delay just in case
|
package/lib/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/lib/index.js
CHANGED
|
@@ -157,7 +157,7 @@ export default class API {
|
|
|
157
157
|
// no-cors issue only with text/plain or not-set Content-Type
|
|
158
158
|
// req.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
|
|
159
159
|
req.send(JSON.stringify({
|
|
160
|
-
trackerVersion: '11.0.
|
|
160
|
+
trackerVersion: '11.0.2',
|
|
161
161
|
projectKey: options.projectKey,
|
|
162
162
|
doNotTrack,
|
|
163
163
|
// TODO: add precise reason (an exact API missing)
|
|
@@ -233,6 +233,12 @@ export default class API {
|
|
|
233
233
|
}
|
|
234
234
|
return this.app.getTabId();
|
|
235
235
|
}
|
|
236
|
+
getUxId() {
|
|
237
|
+
if (this.app === null) {
|
|
238
|
+
return null;
|
|
239
|
+
}
|
|
240
|
+
return this.app.getUxtId();
|
|
241
|
+
}
|
|
236
242
|
sessionID() {
|
|
237
243
|
deprecationWarn("'sessionID' method", "'getSessionID' method", '/');
|
|
238
244
|
return this.getSessionID();
|
|
@@ -113,9 +113,11 @@ export class FetchProxyHandler {
|
|
|
113
113
|
apply(target, _, argsList) {
|
|
114
114
|
const input = argsList[0];
|
|
115
115
|
const init = argsList[1];
|
|
116
|
-
|
|
117
|
-
|
|
116
|
+
if (!input ||
|
|
117
|
+
// @ts-ignore
|
|
118
|
+
(typeof input !== 'string' && !(input === null || input === void 0 ? void 0 : input.url))) {
|
|
118
119
|
return target.apply(window, argsList);
|
|
120
|
+
}
|
|
119
121
|
const isORUrl = input instanceof URL || typeof input === 'string'
|
|
120
122
|
? this.isServiceUrl(String(input))
|
|
121
123
|
: this.isServiceUrl(String(input.url));
|
|
@@ -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,80 @@
|
|
|
1
|
+
import { TEST_START, TASK_IND, SESSION_ID } from './utils.js';
|
|
2
|
+
export default class SignalManager {
|
|
3
|
+
constructor(ingestPoint, getTimestamp, token, testId, storageKey, setStorageKey, removeStorageKey, getStorageKey, getSessionId) {
|
|
4
|
+
this.ingestPoint = ingestPoint;
|
|
5
|
+
this.getTimestamp = getTimestamp;
|
|
6
|
+
this.token = token;
|
|
7
|
+
this.testId = testId;
|
|
8
|
+
this.storageKey = storageKey;
|
|
9
|
+
this.setStorageKey = setStorageKey;
|
|
10
|
+
this.removeStorageKey = removeStorageKey;
|
|
11
|
+
this.getStorageKey = getStorageKey;
|
|
12
|
+
this.getSessionId = getSessionId;
|
|
13
|
+
this.durations = {
|
|
14
|
+
testStart: 0,
|
|
15
|
+
tasks: [],
|
|
16
|
+
};
|
|
17
|
+
this.getDurations = () => {
|
|
18
|
+
return this.durations;
|
|
19
|
+
};
|
|
20
|
+
this.setDurations = (durations) => {
|
|
21
|
+
this.durations.testStart = durations.testStart;
|
|
22
|
+
this.durations.tasks = durations.tasks;
|
|
23
|
+
};
|
|
24
|
+
this.signalTask = (taskId, status, taskAnswer) => {
|
|
25
|
+
if (!taskId)
|
|
26
|
+
return console.error('User Testing: No Task ID Given');
|
|
27
|
+
const taskStart = this.durations.tasks.find((t) => t.taskId === taskId);
|
|
28
|
+
const timestamp = this.getTimestamp();
|
|
29
|
+
const duration = taskStart ? timestamp - taskStart.started : 0;
|
|
30
|
+
return fetch(`${this.ingestPoint}/v1/web/uxt/signals/task`, {
|
|
31
|
+
method: 'POST',
|
|
32
|
+
headers: {
|
|
33
|
+
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
|
|
34
|
+
Authorization: `Bearer ${this.token}`,
|
|
35
|
+
},
|
|
36
|
+
body: JSON.stringify({
|
|
37
|
+
testId: this.testId,
|
|
38
|
+
taskId,
|
|
39
|
+
status,
|
|
40
|
+
duration,
|
|
41
|
+
timestamp,
|
|
42
|
+
taskAnswer,
|
|
43
|
+
}),
|
|
44
|
+
});
|
|
45
|
+
};
|
|
46
|
+
this.signalTest = (status) => {
|
|
47
|
+
const timestamp = this.getTimestamp();
|
|
48
|
+
if (status === 'begin' && this.testId) {
|
|
49
|
+
const sessionId = this.getSessionId();
|
|
50
|
+
this.setStorageKey(SESSION_ID, sessionId);
|
|
51
|
+
this.setStorageKey(this.storageKey, this.testId.toString());
|
|
52
|
+
this.setStorageKey(TEST_START, timestamp.toString());
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
this.removeStorageKey(this.storageKey);
|
|
56
|
+
this.removeStorageKey(TASK_IND);
|
|
57
|
+
this.removeStorageKey(TEST_START);
|
|
58
|
+
}
|
|
59
|
+
const start = this.durations.testStart || timestamp;
|
|
60
|
+
const duration = timestamp - start;
|
|
61
|
+
return fetch(`${this.ingestPoint}/v1/web/uxt/signals/test`, {
|
|
62
|
+
method: 'POST',
|
|
63
|
+
headers: {
|
|
64
|
+
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
|
|
65
|
+
Authorization: `Bearer ${this.token}`,
|
|
66
|
+
},
|
|
67
|
+
body: JSON.stringify({
|
|
68
|
+
testId: this.testId,
|
|
69
|
+
status,
|
|
70
|
+
duration,
|
|
71
|
+
timestamp,
|
|
72
|
+
}),
|
|
73
|
+
});
|
|
74
|
+
};
|
|
75
|
+
const possibleStart = this.getStorageKey(TEST_START);
|
|
76
|
+
if (possibleStart) {
|
|
77
|
+
this.durations.testStart = parseInt(possibleStart, 10);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
@@ -8,18 +8,18 @@ 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;
|