web-tracing-core 2.1.1 → 2.1.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/__test__/css/performance.css +3 -0
- package/__test__/err-batch.spec.ts +47 -0
- package/__test__/err.spec.ts +82 -0
- package/__test__/event.spec.ts +62 -0
- package/__test__/html/performance.html +57 -0
- package/__test__/html/recordscreen.html +39 -0
- package/__test__/http.spec.ts +143 -0
- package/__test__/img/performance.png +0 -0
- package/__test__/js/performance.js +3 -0
- package/__test__/performance.spec.ts +115 -0
- package/__test__/recordscreen.spec.ts +50 -0
- package/__test__/utils/index.ts +132 -0
- package/__test__/utils/pollify.ts +14 -0
- package/__test__/utils.spec.ts +18 -0
- package/{index.cjs → dist/index.cjs} +1 -1
- package/{index.iife.js → dist/index.iife.js} +1 -1
- package/{index.iife.min.js → dist/index.iife.min.js} +1 -1
- package/{index.mjs → dist/index.mjs} +1 -1
- package/dist/package.json +49 -0
- package/index.ts +76 -0
- package/package.json +9 -9
- package/src/common/config.ts +13 -0
- package/src/common/constant.ts +57 -0
- package/src/common/index.ts +2 -0
- package/src/lib/base.ts +129 -0
- package/src/lib/err-batch.ts +134 -0
- package/src/lib/err.ts +323 -0
- package/src/lib/event-dwell.ts +63 -0
- package/src/lib/event.ts +252 -0
- package/src/lib/eventBus.ts +97 -0
- package/src/lib/exportMethods.ts +208 -0
- package/src/lib/http.ts +197 -0
- package/src/lib/intersectionObserver.ts +169 -0
- package/src/lib/line-status.ts +45 -0
- package/src/lib/options.ts +325 -0
- package/src/lib/performance.ts +302 -0
- package/src/lib/pv.ts +199 -0
- package/src/lib/recordscreen.ts +169 -0
- package/src/lib/replace.ts +371 -0
- package/src/lib/sendData.ts +264 -0
- package/src/observer/computed.ts +52 -0
- package/src/observer/config.ts +1 -0
- package/src/observer/dep.ts +21 -0
- package/src/observer/index.ts +91 -0
- package/src/observer/ref.ts +80 -0
- package/src/observer/types.ts +22 -0
- package/src/observer/watch.ts +19 -0
- package/src/observer/watcher.ts +88 -0
- package/src/types/index.ts +126 -0
- package/src/utils/debug.ts +17 -0
- package/src/utils/element.ts +47 -0
- package/src/utils/fingerprintjs.ts +2132 -0
- package/src/utils/getIps.ts +127 -0
- package/src/utils/global.ts +50 -0
- package/src/utils/index.ts +552 -0
- package/src/utils/is.ts +78 -0
- package/src/utils/localStorage.ts +70 -0
- package/src/utils/polyfill.ts +11 -0
- package/src/utils/session.ts +29 -0
- /package/{LICENSE → dist/LICENSE} +0 -0
- /package/{README.md → dist/README.md} +0 -0
- /package/{index.d.ts → dist/index.d.ts} +0 -0
|
@@ -0,0 +1,47 @@
|
|
|
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
|
+
})
|
|
@@ -0,0 +1,82 @@
|
|
|
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
|
+
})
|
|
@@ -0,0 +1,62 @@
|
|
|
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
|
+
})
|
|
@@ -0,0 +1,57 @@
|
|
|
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>
|
|
@@ -0,0 +1,39 @@
|
|
|
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>
|
|
@@ -0,0 +1,143 @@
|
|
|
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
|
|
@@ -0,0 +1,115 @@
|
|
|
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
|
+
await page.waitForFunction(
|
|
69
|
+
() => (window as any).__WebTracingData__ !== undefined
|
|
70
|
+
)
|
|
71
|
+
const webTracingData = (await page.evaluate(
|
|
72
|
+
`window.__WebTracingData__`
|
|
73
|
+
)) as any[]
|
|
74
|
+
|
|
75
|
+
expect(webTracingData).toMatchObject({
|
|
76
|
+
baseInfo,
|
|
77
|
+
eventInfo: [
|
|
78
|
+
{
|
|
79
|
+
eventId: 'page',
|
|
80
|
+
eventType: 'performance'
|
|
81
|
+
}
|
|
82
|
+
]
|
|
83
|
+
})
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
it('async script performance should be captured correctly', async () => {
|
|
87
|
+
const page = await loadTestPage()
|
|
88
|
+
await page.click('.script-button')
|
|
89
|
+
await page.waitForFunction(() => {
|
|
90
|
+
return (window as any).WebTracingTestVar !== undefined
|
|
91
|
+
})
|
|
92
|
+
const webTracingData = await page.evaluate(`window.__WebTracingData__`)
|
|
93
|
+
assertInitiatorType(webTracingData, 'script')
|
|
94
|
+
})
|
|
95
|
+
|
|
96
|
+
it('async link performance should be captured correctly', async () => {
|
|
97
|
+
const page = await loadTestPage()
|
|
98
|
+
await page.click('.link-button')
|
|
99
|
+
await page.waitForFunction(() => {
|
|
100
|
+
const element = document.querySelector('#web-tracing-test-id')!
|
|
101
|
+
const style = window.getComputedStyle(element)
|
|
102
|
+
return style.color === 'rgb(255, 0, 0)'
|
|
103
|
+
})
|
|
104
|
+
const webTracingData = await page.evaluate(`window.__WebTracingData__`)
|
|
105
|
+
assertInitiatorType(webTracingData, 'link')
|
|
106
|
+
})
|
|
107
|
+
|
|
108
|
+
it('async img performance should be captured correctly', async () => {
|
|
109
|
+
const page = await loadTestPage()
|
|
110
|
+
await page.click('.img-button')
|
|
111
|
+
await page.waitForSelector('#performance-img-div img')
|
|
112
|
+
const webTracingData = await page.evaluate(`window.__WebTracingData__`)
|
|
113
|
+
assertInitiatorType(webTracingData, 'img')
|
|
114
|
+
})
|
|
115
|
+
})
|
|
@@ -0,0 +1,50 @@
|
|
|
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(3031)
|
|
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
|
+
async function loadTestPage() {
|
|
31
|
+
const page: Page = await browser.newPage()
|
|
32
|
+
const htmlName = 'recordscreen.html'
|
|
33
|
+
await page.goto(`${serverURL}/${htmlName}`)
|
|
34
|
+
const html = getHtml(`${htmlName}`, code)
|
|
35
|
+
await page.setContent(html)
|
|
36
|
+
await page.waitForFunction(() => {
|
|
37
|
+
return document.readyState === 'complete'
|
|
38
|
+
})
|
|
39
|
+
return page
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
it('error recordscreen should be captured correctly', async () => {
|
|
43
|
+
const page = await loadTestPage()
|
|
44
|
+
await page.click('.code-error-button')
|
|
45
|
+
const webTracingData = await page.evaluate(`window.__WebTracingData__`)
|
|
46
|
+
expect(
|
|
47
|
+
(webTracingData as any).eventInfo[0].recordscreen
|
|
48
|
+
).not.toBeUndefined()
|
|
49
|
+
})
|
|
50
|
+
})
|