web-tracing-core 2.1.0 → 2.1.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/{dist/README.md → README.md} +8 -0
- package/{dist/index.cjs → index.cjs} +24 -5
- package/{dist/index.iife.js → index.iife.js} +24 -5
- package/{dist/index.iife.min.js → index.iife.min.js} +9 -9
- package/{dist/index.mjs → index.mjs} +24 -5
- package/package.json +9 -9
- package/__test__/css/performance.css +0 -3
- package/__test__/err-batch.spec.ts +0 -47
- package/__test__/err.spec.ts +0 -82
- package/__test__/event.spec.ts +0 -62
- package/__test__/html/performance.html +0 -57
- package/__test__/html/recordscreen.html +0 -39
- package/__test__/http.spec.ts +0 -143
- package/__test__/img/performance.png +0 -0
- package/__test__/js/performance.js +0 -3
- package/__test__/performance.spec.ts +0 -112
- package/__test__/recordscreen.spec.ts +0 -50
- package/__test__/utils/index.ts +0 -99
- package/__test__/utils/pollify.ts +0 -14
- package/__test__/utils.spec.ts +0 -18
- package/dist/package.json +0 -49
- package/index.ts +0 -75
- package/src/common/config.ts +0 -13
- package/src/common/constant.ts +0 -57
- package/src/common/index.ts +0 -2
- package/src/lib/base.ts +0 -129
- package/src/lib/err-batch.ts +0 -134
- package/src/lib/err.ts +0 -323
- package/src/lib/event-dwell.ts +0 -63
- package/src/lib/event.ts +0 -252
- package/src/lib/eventBus.ts +0 -97
- package/src/lib/exportMethods.ts +0 -208
- package/src/lib/http.ts +0 -197
- package/src/lib/intersectionObserver.ts +0 -164
- package/src/lib/line-status.ts +0 -45
- package/src/lib/options.ts +0 -325
- package/src/lib/performance.ts +0 -302
- package/src/lib/pv.ts +0 -199
- package/src/lib/recordscreen.ts +0 -169
- package/src/lib/replace.ts +0 -371
- package/src/lib/sendData.ts +0 -264
- package/src/observer/computed.ts +0 -52
- package/src/observer/config.ts +0 -1
- package/src/observer/dep.ts +0 -21
- package/src/observer/index.ts +0 -91
- package/src/observer/ref.ts +0 -80
- package/src/observer/types.ts +0 -22
- package/src/observer/watch.ts +0 -19
- package/src/observer/watcher.ts +0 -88
- package/src/types/index.ts +0 -126
- package/src/utils/debug.ts +0 -17
- package/src/utils/element.ts +0 -47
- package/src/utils/fingerprintjs.ts +0 -2132
- package/src/utils/getIps.ts +0 -127
- package/src/utils/global.ts +0 -49
- package/src/utils/index.ts +0 -551
- package/src/utils/is.ts +0 -78
- package/src/utils/localStorage.ts +0 -70
- package/src/utils/session.ts +0 -27
- /package/{dist/LICENSE → LICENSE} +0 -0
- /package/{dist/index.d.ts → index.d.ts} +0 -0
|
@@ -1,3 +1,14 @@
|
|
|
1
|
+
if (typeof window === "undefined" && typeof global !== "undefined") {
|
|
2
|
+
global.window = global;
|
|
3
|
+
global.self = global;
|
|
4
|
+
if (!global.requestAnimationFrame) {
|
|
5
|
+
global.requestAnimationFrame = (callback) => setTimeout(callback, 0);
|
|
6
|
+
}
|
|
7
|
+
if (!global.cancelAnimationFrame) {
|
|
8
|
+
global.cancelAnimationFrame = (id) => clearTimeout(id);
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
|
|
1
12
|
function isType(type) {
|
|
2
13
|
return function(value) {
|
|
3
14
|
return Object.prototype.toString.call(value) === `[object ${type}]`;
|
|
@@ -18,7 +29,7 @@ function isEmpty(wat) {
|
|
|
18
29
|
}
|
|
19
30
|
|
|
20
31
|
const isBrowserEnv = isWindow(typeof window !== "undefined" ? window : 0);
|
|
21
|
-
const isElectronEnv = !!window
|
|
32
|
+
const isElectronEnv = typeof window !== "undefined" && !!window.process?.versions?.electron;
|
|
22
33
|
const isTestEnv = typeof navigator !== "undefined" && navigator.userAgent.includes("jsdom") || // @ts-expect-error: jsdom
|
|
23
34
|
typeof window !== "undefined" && window.jsdom;
|
|
24
35
|
function getGlobal() {
|
|
@@ -677,6 +688,8 @@ function uuid() {
|
|
|
677
688
|
return `${guid.slice(0, 8)}-${guid.slice(8, 16)}-${guid.slice(16)}`;
|
|
678
689
|
}
|
|
679
690
|
function getCookieByName(name) {
|
|
691
|
+
if (typeof document === "undefined")
|
|
692
|
+
return void 0;
|
|
680
693
|
const result = document.cookie.match(new RegExp(`${name}=([^;]+)(;|$)`));
|
|
681
694
|
return result ? result[1] : void 0;
|
|
682
695
|
}
|
|
@@ -760,7 +773,7 @@ const arrayFilter = Array.prototype.filter || function filterPolyfill(fn) {
|
|
|
760
773
|
function filter(arr, fn) {
|
|
761
774
|
return arrayFilter.call(arr, fn);
|
|
762
775
|
}
|
|
763
|
-
const nextTime = window.requestIdleCallback || window.requestAnimationFrame || ((callback) => setTimeout(callback, 17));
|
|
776
|
+
const nextTime = typeof window !== "undefined" && window.requestIdleCallback || typeof window !== "undefined" && window.requestAnimationFrame || ((callback) => setTimeout(callback, 17));
|
|
764
777
|
function isObjectOverSizeLimit(object, limitInKB) {
|
|
765
778
|
const serializedObject = JSON.stringify(object);
|
|
766
779
|
const sizeInBytes = new TextEncoder().encode(serializedObject).length;
|
|
@@ -809,7 +822,7 @@ function off(target, eventName, handler, opitons = false) {
|
|
|
809
822
|
target.removeEventListener(eventName, handler, opitons);
|
|
810
823
|
}
|
|
811
824
|
|
|
812
|
-
var version$1 = "2.1.
|
|
825
|
+
var version$1 = "2.1.1";
|
|
813
826
|
|
|
814
827
|
const DEVICE_KEY = "_webtracing_device_id";
|
|
815
828
|
const SESSION_KEY = "_webtracing_session_id";
|
|
@@ -2832,7 +2845,9 @@ function refreshSession() {
|
|
|
2832
2845
|
function getSessionId() {
|
|
2833
2846
|
return getCookieByName(SESSION_KEY) || refreshSession();
|
|
2834
2847
|
}
|
|
2835
|
-
|
|
2848
|
+
if (typeof document !== "undefined") {
|
|
2849
|
+
refreshSession();
|
|
2850
|
+
}
|
|
2836
2851
|
|
|
2837
2852
|
function is_ipv4(d) {
|
|
2838
2853
|
return regex_v4.test(d);
|
|
@@ -15677,7 +15692,11 @@ class Intersection {
|
|
|
15677
15692
|
sendData.emit({
|
|
15678
15693
|
eventType: SEDNEVENTTYPES.INTERSECTION,
|
|
15679
15694
|
triggerPageUrl: getLocationHref(),
|
|
15680
|
-
|
|
15695
|
+
threshold: targetObj.threshold,
|
|
15696
|
+
observeTime: targetObj.observeTime,
|
|
15697
|
+
showTime: targetObj.showTime,
|
|
15698
|
+
showEndTime: targetObj.showEndTime,
|
|
15699
|
+
params: targetObj.params
|
|
15681
15700
|
});
|
|
15682
15701
|
}
|
|
15683
15702
|
/**
|
package/package.json
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "web-tracing-core",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.1",
|
|
4
4
|
"description": "基于 JS 跨平台插件,为前端项目提供【 埋点、行为、性能、异常、请求、资源、路由、曝光、录屏 】监控手段",
|
|
5
|
-
"main": "./
|
|
6
|
-
"module": "./
|
|
7
|
-
"jsdelivr": "./
|
|
8
|
-
"types": "./
|
|
5
|
+
"main": "./index.mjs",
|
|
6
|
+
"module": "./index.mjs",
|
|
7
|
+
"jsdelivr": "./index.iife.min.js",
|
|
8
|
+
"types": "./index.d.ts",
|
|
9
9
|
"sideEffects": false,
|
|
10
10
|
"exports": {
|
|
11
11
|
".": {
|
|
12
|
-
"import": "./
|
|
13
|
-
"require": "./
|
|
14
|
-
"types": "./
|
|
12
|
+
"import": "./index.mjs",
|
|
13
|
+
"require": "./index.cjs",
|
|
14
|
+
"types": "./index.d.ts"
|
|
15
15
|
},
|
|
16
16
|
"./*": "./*"
|
|
17
17
|
},
|
|
@@ -45,5 +45,5 @@
|
|
|
45
45
|
"url": "https://github.com/M-cheng-web/web-tracing/issues"
|
|
46
46
|
},
|
|
47
47
|
"homepage": "https://github.com/M-cheng-web/web-tracing#readme",
|
|
48
|
-
"unpkg": "./
|
|
48
|
+
"unpkg": "./index.iife.min.js"
|
|
49
49
|
}
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import { init } from '../index'
|
|
2
|
-
import { _support } from '../src/utils/global'
|
|
3
|
-
|
|
4
|
-
describe('err', () => {
|
|
5
|
-
beforeAll(() => {
|
|
6
|
-
init({
|
|
7
|
-
dsn: 'http://unit-test.com',
|
|
8
|
-
appName: 'unit-test',
|
|
9
|
-
error: true,
|
|
10
|
-
recordScreen: false,
|
|
11
|
-
scopeError: true
|
|
12
|
-
})
|
|
13
|
-
})
|
|
14
|
-
|
|
15
|
-
function proxyEmit() {
|
|
16
|
-
const testResult = { error: null, spy: vi.fn() }
|
|
17
|
-
_support.sendData.emit = (e: any) => {
|
|
18
|
-
testResult.spy()
|
|
19
|
-
testResult.error = e
|
|
20
|
-
}
|
|
21
|
-
return testResult
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
it('batch error should be captured correctly', () => {
|
|
25
|
-
const testResult = proxyEmit()
|
|
26
|
-
for (let i = 0; i < 50; i++) {
|
|
27
|
-
const errorEvent = new window.ErrorEvent('error', {
|
|
28
|
-
filename: 'test.js',
|
|
29
|
-
lineno: 10,
|
|
30
|
-
colno: 20,
|
|
31
|
-
error: new Error('code error')
|
|
32
|
-
})
|
|
33
|
-
window.dispatchEvent(errorEvent)
|
|
34
|
-
}
|
|
35
|
-
expect(testResult.spy).toHaveBeenCalledTimes(1)
|
|
36
|
-
expect(testResult.error).toMatchObject([
|
|
37
|
-
{
|
|
38
|
-
line: 10,
|
|
39
|
-
col: 20,
|
|
40
|
-
eventId: 'code',
|
|
41
|
-
eventType: 'error',
|
|
42
|
-
errMessage: 'code error',
|
|
43
|
-
batchError: true
|
|
44
|
-
}
|
|
45
|
-
])
|
|
46
|
-
})
|
|
47
|
-
})
|
package/__test__/err.spec.ts
DELETED
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
import { init } from '../index'
|
|
2
|
-
import { _support } from '../src/utils/global'
|
|
3
|
-
import { PromiseRejectionEvent } from './utils/pollify'
|
|
4
|
-
|
|
5
|
-
describe('err', () => {
|
|
6
|
-
beforeAll(() => {
|
|
7
|
-
init({
|
|
8
|
-
dsn: 'http://unit-test.com',
|
|
9
|
-
appName: 'unit-test',
|
|
10
|
-
error: true,
|
|
11
|
-
recordScreen: false,
|
|
12
|
-
ignoreErrors: [/^ignore/]
|
|
13
|
-
})
|
|
14
|
-
})
|
|
15
|
-
|
|
16
|
-
function proxyEmit() {
|
|
17
|
-
const testResult = { error: null, spy: vi.fn() }
|
|
18
|
-
_support.sendData.emit = (e: any) => {
|
|
19
|
-
testResult.spy()
|
|
20
|
-
testResult.error = e
|
|
21
|
-
}
|
|
22
|
-
return testResult
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
it('code error should be captured correctly', () => {
|
|
26
|
-
const testResult = proxyEmit()
|
|
27
|
-
const errorEvent = new window.ErrorEvent('error', {
|
|
28
|
-
filename: 'test.js',
|
|
29
|
-
lineno: 10,
|
|
30
|
-
colno: 20,
|
|
31
|
-
error: new Error('code error')
|
|
32
|
-
})
|
|
33
|
-
window.dispatchEvent(errorEvent)
|
|
34
|
-
expect(testResult.spy).toHaveBeenCalledTimes(1)
|
|
35
|
-
expect(testResult.error).toMatchObject({
|
|
36
|
-
line: 10,
|
|
37
|
-
col: 20,
|
|
38
|
-
eventId: 'code',
|
|
39
|
-
eventType: 'error',
|
|
40
|
-
errMessage: 'code error'
|
|
41
|
-
})
|
|
42
|
-
})
|
|
43
|
-
|
|
44
|
-
it('unhandledrejection error should be captured correctly', () => {
|
|
45
|
-
const testResult = proxyEmit()
|
|
46
|
-
const errorEvent = new PromiseRejectionEvent('unhandledrejection', {
|
|
47
|
-
reason: 'unhandledrejection error',
|
|
48
|
-
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
49
|
-
promise: Promise.reject('unhandledrejection error').catch(() => {})
|
|
50
|
-
})
|
|
51
|
-
window.dispatchEvent(errorEvent)
|
|
52
|
-
expect(testResult.spy).toHaveBeenCalledTimes(1)
|
|
53
|
-
expect(testResult.error).toMatchObject({
|
|
54
|
-
eventId: 'reject',
|
|
55
|
-
eventType: 'error',
|
|
56
|
-
errMessage: 'unhandledrejection error'
|
|
57
|
-
})
|
|
58
|
-
})
|
|
59
|
-
|
|
60
|
-
it('console error should be captured correctly', () => {
|
|
61
|
-
const testResult = proxyEmit()
|
|
62
|
-
console.error('console error')
|
|
63
|
-
expect(testResult.spy).toHaveBeenCalledTimes(1)
|
|
64
|
-
expect(testResult.error).toMatchObject({
|
|
65
|
-
eventId: 'console.error',
|
|
66
|
-
eventType: 'error',
|
|
67
|
-
errMessage: 'console error'
|
|
68
|
-
})
|
|
69
|
-
})
|
|
70
|
-
|
|
71
|
-
it('option ignoreErrors should work', () => {
|
|
72
|
-
const testResult = proxyEmit()
|
|
73
|
-
const errorEvent = new window.ErrorEvent('error', {
|
|
74
|
-
filename: 'test.js',
|
|
75
|
-
lineno: 10,
|
|
76
|
-
colno: 20,
|
|
77
|
-
error: new Error('ignore error')
|
|
78
|
-
})
|
|
79
|
-
window.dispatchEvent(errorEvent)
|
|
80
|
-
expect(testResult.spy).toHaveBeenCalledTimes(0)
|
|
81
|
-
})
|
|
82
|
-
})
|
package/__test__/event.spec.ts
DELETED
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
import { init } from '../index'
|
|
2
|
-
import { _support, _global } from '../src/utils/global'
|
|
3
|
-
import { JSDOM } from 'jsdom'
|
|
4
|
-
|
|
5
|
-
describe('err', () => {
|
|
6
|
-
beforeAll(() => {
|
|
7
|
-
const dom = new JSDOM(`
|
|
8
|
-
<!DOCTYPE html>
|
|
9
|
-
<html lang="en">
|
|
10
|
-
<head>
|
|
11
|
-
<meta charset="UTF-8">
|
|
12
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
13
|
-
<title>Test</title>
|
|
14
|
-
</head>
|
|
15
|
-
<body>
|
|
16
|
-
<div
|
|
17
|
-
data-warden-title="test-title"
|
|
18
|
-
data-warden-event-id="test-event-id"
|
|
19
|
-
>
|
|
20
|
-
<div data-warden-id="test-warden-id">
|
|
21
|
-
<button id="btn">test</button>
|
|
22
|
-
</div>
|
|
23
|
-
</div>
|
|
24
|
-
</body>
|
|
25
|
-
</html>
|
|
26
|
-
`)
|
|
27
|
-
// @ts-expect-error: expected
|
|
28
|
-
_global.document = dom.window.document
|
|
29
|
-
init({
|
|
30
|
-
dsn: 'http://unit-test.com',
|
|
31
|
-
appName: 'unit-test',
|
|
32
|
-
event: true,
|
|
33
|
-
recordScreen: false
|
|
34
|
-
})
|
|
35
|
-
})
|
|
36
|
-
|
|
37
|
-
function proxyEmit() {
|
|
38
|
-
const testResult = { info: null, spy: vi.fn() }
|
|
39
|
-
_support.sendData.emit = (e: any) => {
|
|
40
|
-
testResult.spy()
|
|
41
|
-
testResult.info = e
|
|
42
|
-
}
|
|
43
|
-
return testResult
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
it('event should be captured correctly', async () => {
|
|
47
|
-
const testResult = proxyEmit()
|
|
48
|
-
|
|
49
|
-
const button = document.getElementById('btn')!
|
|
50
|
-
button.click()
|
|
51
|
-
expect(testResult.spy).toHaveBeenCalledTimes(1)
|
|
52
|
-
expect(testResult.info).toMatchObject({
|
|
53
|
-
eventId: 'test-event-id',
|
|
54
|
-
eventType: 'click',
|
|
55
|
-
title: 'test-title',
|
|
56
|
-
elementPath: 'div',
|
|
57
|
-
params: {
|
|
58
|
-
id: 'test-warden-id'
|
|
59
|
-
}
|
|
60
|
-
})
|
|
61
|
-
})
|
|
62
|
-
})
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="UTF-8" />
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
-
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
|
|
7
|
-
<title>performance test</title>
|
|
8
|
-
</head>
|
|
9
|
-
|
|
10
|
-
<body>
|
|
11
|
-
<div>
|
|
12
|
-
<div>Performance 异步加载资源</div>
|
|
13
|
-
<button class="script-button" onclick="performanceAddScript()">插入正确Script</button>
|
|
14
|
-
<button class="link-button" id="web-tracing-test-id" onclick="performanceAddLink()" >插入Link</button>
|
|
15
|
-
<button class="img-button" onclick="performanceAddImg()">插入Img</button>
|
|
16
|
-
<div id="performance-img-div"></div>
|
|
17
|
-
</div>
|
|
18
|
-
</body>
|
|
19
|
-
|
|
20
|
-
<script>
|
|
21
|
-
WebTracing.init({
|
|
22
|
-
dsn: 'http://1.15.224.10:22/trackweb/tra',
|
|
23
|
-
appName: 'cxh',
|
|
24
|
-
performance: true,
|
|
25
|
-
userUuid: 'init_userUuid',
|
|
26
|
-
cacheMaxLength: 1,
|
|
27
|
-
cacheWatingTime: 0,
|
|
28
|
-
beforeSendData(data) {
|
|
29
|
-
window.__WebTracingData__ = data
|
|
30
|
-
return false
|
|
31
|
-
}
|
|
32
|
-
})
|
|
33
|
-
|
|
34
|
-
function performanceAddScript() {
|
|
35
|
-
const script = document.createElement("script");
|
|
36
|
-
script.src = "http://localhost:3030/js/performance.js";
|
|
37
|
-
document.head.appendChild(script);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
function performanceAddLink() {
|
|
41
|
-
const link = document.createElement("link");
|
|
42
|
-
link.type = "text/css";
|
|
43
|
-
link.rel = "stylesheet";
|
|
44
|
-
link.href = "http://localhost:3030/css/performance.css";
|
|
45
|
-
document.head.appendChild(link);
|
|
46
|
-
}
|
|
47
|
-
function performanceAddImg() {
|
|
48
|
-
const img = new Image();
|
|
49
|
-
img.addEventListener('load', function() {
|
|
50
|
-
const div = document.getElementById("performance-img-div");
|
|
51
|
-
div.style = "width: 400px; height: 400px; overflow: hidden;";
|
|
52
|
-
div.appendChild(img);
|
|
53
|
-
}, false);
|
|
54
|
-
img.src = `http://localhost:3030/img/performance.png`;
|
|
55
|
-
}
|
|
56
|
-
</script>
|
|
57
|
-
</html>
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="UTF-8" />
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
-
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
|
|
7
|
-
<title>recordscreen test</title>
|
|
8
|
-
</head>
|
|
9
|
-
|
|
10
|
-
<body>
|
|
11
|
-
<div>
|
|
12
|
-
<div>recordscreen</div>
|
|
13
|
-
<button class="code-error-button" onclick="codeError()">
|
|
14
|
-
代码错误
|
|
15
|
-
</button>
|
|
16
|
-
</div>
|
|
17
|
-
</body>
|
|
18
|
-
|
|
19
|
-
<script>
|
|
20
|
-
WebTracing.init({
|
|
21
|
-
dsn: 'http://1.15.224.10:22/trackweb/tra',
|
|
22
|
-
appName: 'cxh',
|
|
23
|
-
userUuid: 'init_userUuid',
|
|
24
|
-
cacheMaxLength: 1,
|
|
25
|
-
cacheWatingTime: 0,
|
|
26
|
-
error: true,
|
|
27
|
-
recordscreen: true,
|
|
28
|
-
beforeSendData(data) {
|
|
29
|
-
window.__WebTracingData__ = data
|
|
30
|
-
return false
|
|
31
|
-
}
|
|
32
|
-
})
|
|
33
|
-
|
|
34
|
-
function codeError() {
|
|
35
|
-
const a = {}
|
|
36
|
-
a.split('/')
|
|
37
|
-
}
|
|
38
|
-
</script>
|
|
39
|
-
</html>
|
package/__test__/http.spec.ts
DELETED
|
@@ -1,143 +0,0 @@
|
|
|
1
|
-
import { init } from '../index'
|
|
2
|
-
import { _support } from '../src/utils/global'
|
|
3
|
-
import express from 'express'
|
|
4
|
-
import http from 'http'
|
|
5
|
-
|
|
6
|
-
const port = 7889
|
|
7
|
-
let server: http.Server
|
|
8
|
-
|
|
9
|
-
describe('err', () => {
|
|
10
|
-
beforeAll(() => {
|
|
11
|
-
init({
|
|
12
|
-
dsn: 'http://unit-test.com',
|
|
13
|
-
appName: 'unit-test',
|
|
14
|
-
error: true,
|
|
15
|
-
recordScreen: false,
|
|
16
|
-
performance: {
|
|
17
|
-
core: false,
|
|
18
|
-
server: true
|
|
19
|
-
}
|
|
20
|
-
})
|
|
21
|
-
|
|
22
|
-
const app = express()
|
|
23
|
-
app.all('*', function (_, req, next) {
|
|
24
|
-
req.header('Access-Control-Allow-Origin', '*')
|
|
25
|
-
req.header('Access-Control-Allow-Headers', 'Content-Type')
|
|
26
|
-
req.header('Access-Control-Allow-Methods', '*')
|
|
27
|
-
req.header('Content-Type', 'application/json;charset=utf-8')
|
|
28
|
-
next()
|
|
29
|
-
})
|
|
30
|
-
app.post('/setList', (req, res) => {
|
|
31
|
-
res.send({
|
|
32
|
-
code: 200,
|
|
33
|
-
meaage: '设置成功'
|
|
34
|
-
})
|
|
35
|
-
})
|
|
36
|
-
server && server.close()
|
|
37
|
-
server = app.listen(port)
|
|
38
|
-
})
|
|
39
|
-
|
|
40
|
-
afterAll(() => {
|
|
41
|
-
server.close()
|
|
42
|
-
})
|
|
43
|
-
|
|
44
|
-
function proxyEmit() {
|
|
45
|
-
const testResult: any = { info: [], spy: vi.fn() }
|
|
46
|
-
_support.sendData.emit = (e: any) => {
|
|
47
|
-
testResult.spy()
|
|
48
|
-
testResult.info.push(e)
|
|
49
|
-
}
|
|
50
|
-
return testResult
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
function sendRequest(url: string, type: 'xhr' | 'fetch' = 'xhr') {
|
|
54
|
-
const body = { username: 'example', password: '123456' }
|
|
55
|
-
return type === 'xhr'
|
|
56
|
-
? new Promise(resolve => {
|
|
57
|
-
const xhr = new XMLHttpRequest()
|
|
58
|
-
xhr.open('post', url)
|
|
59
|
-
xhr.setRequestHeader('content-type', 'application/json')
|
|
60
|
-
xhr.send(JSON.stringify(body))
|
|
61
|
-
xhr.onreadystatechange = function () {
|
|
62
|
-
if (xhr.readyState === 4) {
|
|
63
|
-
resolve(xhr.responseText)
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
})
|
|
67
|
-
: fetch(url, {
|
|
68
|
-
method: 'POST',
|
|
69
|
-
body: JSON.stringify(body),
|
|
70
|
-
headers: {
|
|
71
|
-
'Content-Type': 'application/json'
|
|
72
|
-
}
|
|
73
|
-
})
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
it('xhr error should be captured correctly', async () => {
|
|
77
|
-
const testResult = proxyEmit()
|
|
78
|
-
await sendRequest(`http://localhost:${port}/invalid-url`)
|
|
79
|
-
expect(testResult.spy).toHaveBeenCalledTimes(1)
|
|
80
|
-
expect(testResult.info).toMatchObject([
|
|
81
|
-
{
|
|
82
|
-
errMessage: 'Not Found',
|
|
83
|
-
eventId: 'server',
|
|
84
|
-
eventType: 'error',
|
|
85
|
-
params: '{"username":"example","password":"123456"}',
|
|
86
|
-
recordscreen: null,
|
|
87
|
-
requestMethod: 'post',
|
|
88
|
-
requestType: 'xhr',
|
|
89
|
-
responseStatus: 404
|
|
90
|
-
}
|
|
91
|
-
])
|
|
92
|
-
})
|
|
93
|
-
|
|
94
|
-
it('xhr performance should be captured correctly', async () => {
|
|
95
|
-
const testResult = proxyEmit()
|
|
96
|
-
await sendRequest(`http://localhost:${port}/setList`)
|
|
97
|
-
expect(testResult.spy).toHaveBeenCalledTimes(1)
|
|
98
|
-
expect(testResult.info).toMatchObject([
|
|
99
|
-
{
|
|
100
|
-
eventId: 'server',
|
|
101
|
-
eventType: 'performance',
|
|
102
|
-
params: '{"username":"example","password":"123456"}',
|
|
103
|
-
requestMethod: 'post',
|
|
104
|
-
requestType: 'xhr',
|
|
105
|
-
responseStatus: 200
|
|
106
|
-
}
|
|
107
|
-
])
|
|
108
|
-
})
|
|
109
|
-
|
|
110
|
-
it('fetch error should be captured correctly', async () => {
|
|
111
|
-
const testResult = proxyEmit()
|
|
112
|
-
await sendRequest(`http://localhost:${port}/invalid-url`, 'fetch')
|
|
113
|
-
expect(testResult.spy).toHaveBeenCalledTimes(1)
|
|
114
|
-
expect(testResult.info).toMatchObject([
|
|
115
|
-
{
|
|
116
|
-
errMessage: 'Not Found',
|
|
117
|
-
eventId: 'server',
|
|
118
|
-
eventType: 'error',
|
|
119
|
-
params: '{"username":"example","password":"123456"}',
|
|
120
|
-
recordscreen: null,
|
|
121
|
-
requestMethod: 'post',
|
|
122
|
-
requestType: 'fetch',
|
|
123
|
-
responseStatus: 404
|
|
124
|
-
}
|
|
125
|
-
])
|
|
126
|
-
})
|
|
127
|
-
|
|
128
|
-
it('fetch performance should be captured correctly', async () => {
|
|
129
|
-
const testResult = proxyEmit()
|
|
130
|
-
await sendRequest(`http://localhost:${port}/setList`, 'fetch')
|
|
131
|
-
expect(testResult.spy).toHaveBeenCalledTimes(1)
|
|
132
|
-
expect(testResult.info).toMatchObject([
|
|
133
|
-
{
|
|
134
|
-
eventId: 'server',
|
|
135
|
-
eventType: 'performance',
|
|
136
|
-
params: '{"username":"example","password":"123456"}',
|
|
137
|
-
requestMethod: 'post',
|
|
138
|
-
requestType: 'fetch',
|
|
139
|
-
responseStatus: 200
|
|
140
|
-
}
|
|
141
|
-
])
|
|
142
|
-
})
|
|
143
|
-
})
|
|
Binary file
|
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
import fs from 'fs'
|
|
2
|
-
import path from 'path'
|
|
3
|
-
import http from 'http'
|
|
4
|
-
|
|
5
|
-
import { getServerURL, startServer, launchPuppeteer, getHtml } from './utils'
|
|
6
|
-
import { Browser, Page } from 'puppeteer'
|
|
7
|
-
|
|
8
|
-
describe('err', () => {
|
|
9
|
-
vi.setConfig({ testTimeout: 30_000, hookTimeout: 30_000 })
|
|
10
|
-
|
|
11
|
-
let code: string
|
|
12
|
-
let serverURL: string
|
|
13
|
-
let server: http.Server
|
|
14
|
-
let browser: Browser
|
|
15
|
-
|
|
16
|
-
beforeAll(async () => {
|
|
17
|
-
server = await startServer()
|
|
18
|
-
serverURL = getServerURL(server)
|
|
19
|
-
browser = await launchPuppeteer()
|
|
20
|
-
|
|
21
|
-
const bundlePath = path.resolve(__dirname, '../dist/index.iife.js')
|
|
22
|
-
code = fs.readFileSync(bundlePath, 'utf8')
|
|
23
|
-
})
|
|
24
|
-
|
|
25
|
-
afterAll(async () => {
|
|
26
|
-
browser && (await browser.close())
|
|
27
|
-
server && server.close()
|
|
28
|
-
})
|
|
29
|
-
|
|
30
|
-
const baseInfo = {
|
|
31
|
-
appCode: '',
|
|
32
|
-
appName: 'cxh',
|
|
33
|
-
clientHeight: 1080,
|
|
34
|
-
clientWidth: 1920,
|
|
35
|
-
vendor: 'Google Inc.'
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
async function loadTestPage() {
|
|
39
|
-
const page: Page = await browser.newPage()
|
|
40
|
-
const htmlName = 'performance.html'
|
|
41
|
-
await page.goto(`${serverURL}/${htmlName}`)
|
|
42
|
-
const html = getHtml(`${htmlName}`, code)
|
|
43
|
-
await page.setContent(html)
|
|
44
|
-
await page.waitForFunction(() => {
|
|
45
|
-
return document.readyState === 'complete'
|
|
46
|
-
})
|
|
47
|
-
return page
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
function assertInitiatorType(
|
|
51
|
-
data: any,
|
|
52
|
-
initiatorType: 'script' | 'link' | 'img'
|
|
53
|
-
) {
|
|
54
|
-
expect(data).toMatchObject({
|
|
55
|
-
baseInfo,
|
|
56
|
-
eventInfo: [
|
|
57
|
-
{
|
|
58
|
-
eventId: 'resource',
|
|
59
|
-
eventType: 'performance',
|
|
60
|
-
initiatorType: initiatorType
|
|
61
|
-
}
|
|
62
|
-
]
|
|
63
|
-
})
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
it('firstResource performance should be captured correctly', async () => {
|
|
67
|
-
const page = await loadTestPage()
|
|
68
|
-
const webTracingData = (await page.evaluate(
|
|
69
|
-
`window.__WebTracingData__`
|
|
70
|
-
)) as any[]
|
|
71
|
-
|
|
72
|
-
expect(webTracingData).toMatchObject({
|
|
73
|
-
baseInfo,
|
|
74
|
-
eventInfo: [
|
|
75
|
-
{
|
|
76
|
-
eventId: 'page',
|
|
77
|
-
eventType: 'performance'
|
|
78
|
-
}
|
|
79
|
-
]
|
|
80
|
-
})
|
|
81
|
-
})
|
|
82
|
-
|
|
83
|
-
it('async script performance should be captured correctly', async () => {
|
|
84
|
-
const page = await loadTestPage()
|
|
85
|
-
await page.click('.script-button')
|
|
86
|
-
await page.waitForFunction(() => {
|
|
87
|
-
return (window as any).WebTracingTestVar !== undefined
|
|
88
|
-
})
|
|
89
|
-
const webTracingData = await page.evaluate(`window.__WebTracingData__`)
|
|
90
|
-
assertInitiatorType(webTracingData, 'script')
|
|
91
|
-
})
|
|
92
|
-
|
|
93
|
-
it('async link performance should be captured correctly', async () => {
|
|
94
|
-
const page = await loadTestPage()
|
|
95
|
-
await page.click('.link-button')
|
|
96
|
-
await page.waitForFunction(() => {
|
|
97
|
-
const element = document.querySelector('#web-tracing-test-id')!
|
|
98
|
-
const style = window.getComputedStyle(element)
|
|
99
|
-
return style.color === 'rgb(255, 0, 0)'
|
|
100
|
-
})
|
|
101
|
-
const webTracingData = await page.evaluate(`window.__WebTracingData__`)
|
|
102
|
-
assertInitiatorType(webTracingData, 'link')
|
|
103
|
-
})
|
|
104
|
-
|
|
105
|
-
it('async img performance should be captured correctly', async () => {
|
|
106
|
-
const page = await loadTestPage()
|
|
107
|
-
await page.click('.img-button')
|
|
108
|
-
await page.waitForSelector('#performance-img-div img')
|
|
109
|
-
const webTracingData = await page.evaluate(`window.__WebTracingData__`)
|
|
110
|
-
assertInitiatorType(webTracingData, 'img')
|
|
111
|
-
})
|
|
112
|
-
})
|