Skip to content

Commit 587d437

Browse files
committed
Unit test case for Network log capture
1 parent 9087aea commit 587d437

File tree

2 files changed

+203
-0
lines changed

2 files changed

+203
-0
lines changed
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/** @vitest-environment happy-dom */
2+
import { describe, it, expect, beforeEach, afterEach } from 'vitest'
3+
import { NetworkRequestCollector } from '../src/collectors/networkRequests.js'
4+
5+
describe('NetworkRequestCollector', () => {
6+
let collector: NetworkRequestCollector
7+
8+
beforeEach(() => {
9+
collector = new NetworkRequestCollector()
10+
})
11+
12+
afterEach(() => {
13+
collector.clear()
14+
})
15+
16+
it('should initialize, clear, and return artifacts correctly', () => {
17+
// Test initialization
18+
const artifacts = collector.getArtifacts()
19+
expect(artifacts).toEqual([])
20+
expect(Array.isArray(artifacts)).toBe(true)
21+
expect(artifacts).toHaveLength(0)
22+
23+
// Test clear functionality
24+
collector.clear()
25+
const clearedArtifacts = collector.getArtifacts()
26+
expect(clearedArtifacts).toEqual([])
27+
expect(clearedArtifacts).toHaveLength(0)
28+
29+
// Test multiple clears are safe
30+
collector.clear()
31+
expect(collector.getArtifacts()).toEqual([])
32+
33+
// Test reference consistency
34+
const artifacts1 = collector.getArtifacts()
35+
const artifacts2 = collector.getArtifacts()
36+
expect(artifacts1).toBe(artifacts2)
37+
expect(artifacts1).toBeDefined()
38+
expect(artifacts1).not.toBeNull()
39+
})
40+
})
Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
import { describe, it, expect, beforeEach, afterEach } from 'vitest'
2+
import { SessionCapturer } from '../src/session.js'
3+
4+
describe('SessionCapturer - Network Request Capture', () => {
5+
let capturer: SessionCapturer
6+
7+
// Helper to create request event
8+
const createRequestEvent = (id: string, url: string, method = 'GET') => ({
9+
request: {
10+
request: id,
11+
url,
12+
method,
13+
headers: [],
14+
timings: { timeOrigin: 1000 }
15+
}
16+
})
17+
18+
// Helper to create response event
19+
const createResponseEvent = (
20+
id: string,
21+
url: string,
22+
options: {
23+
status?: number
24+
statusText?: string
25+
contentType?: string
26+
size?: number
27+
timeOrigin?: number
28+
} = {}
29+
) => {
30+
const headers = options.contentType
31+
? [
32+
{
33+
name: 'Content-Type',
34+
value: { type: 'string', value: options.contentType }
35+
}
36+
]
37+
: []
38+
39+
return {
40+
request: { request: id },
41+
response: {
42+
url,
43+
status: options.status ?? 200,
44+
statusText: options.statusText ?? 'OK',
45+
headers,
46+
fromCache: false,
47+
bytesReceived: options.size ?? 1024,
48+
timings: { timeOrigin: options.timeOrigin ?? 1500 }
49+
}
50+
}
51+
}
52+
53+
// Helper to verify request properties
54+
const verifyRequest = (
55+
req: any,
56+
expected: {
57+
url: string
58+
method?: string
59+
status?: number
60+
contentType?: string
61+
size?: number
62+
}
63+
) => {
64+
expect(req).toBeDefined()
65+
expect(req.url).toBe(expected.url)
66+
expect(req.method).toBe(expected.method ?? 'GET')
67+
expect(req.status).toBe(expected.status ?? 200)
68+
expect(req.statusText).toBe('OK')
69+
if (expected.contentType) {
70+
expect(req.responseHeaders).toBeDefined()
71+
expect(req.responseHeaders?.['content-type']).toBe(expected.contentType)
72+
}
73+
if (expected.size) {
74+
expect(req.size).toBe(expected.size)
75+
}
76+
expect(req.time).toBeDefined()
77+
expect(typeof req.time).toBe('number')
78+
expect(req.time).toBeGreaterThanOrEqual(0)
79+
}
80+
81+
beforeEach(() => {
82+
capturer = new SessionCapturer()
83+
})
84+
85+
afterEach(() => {
86+
capturer.networkRequests = []
87+
})
88+
89+
it('should capture, merge, and filter network requests correctly', () => {
90+
// Test 1: Successful request capture and merge
91+
const req1 = createRequestEvent('1', 'https://api.example.com/users')
92+
capturer.handleNetworkRequestStarted(req1 as any)
93+
94+
const res1 = createResponseEvent('1', 'https://api.example.com/users', {
95+
contentType: 'application/json',
96+
size: 1024
97+
})
98+
capturer.handleNetworkResponseCompleted(res1 as any)
99+
100+
expect(capturer.networkRequests).toHaveLength(1)
101+
verifyRequest(capturer.networkRequests[0], {
102+
url: 'https://api.example.com/users',
103+
method: 'GET',
104+
status: 200,
105+
contentType: 'application/json',
106+
size: 1024
107+
})
108+
109+
// Test 2: Request without content-type should be filtered
110+
const req2 = createRequestEvent('2', 'https://api.example.com/no-type')
111+
capturer.handleNetworkRequestStarted(req2 as any)
112+
113+
const res2 = createResponseEvent('2', 'https://api.example.com/no-type', {})
114+
capturer.handleNetworkResponseCompleted(res2 as any)
115+
116+
// Should still have only 1 request (the first one)
117+
expect(capturer.networkRequests).toHaveLength(1)
118+
})
119+
120+
it('should handle multiple concurrent requests', () => {
121+
const endpoints = ['endpoint1', 'endpoint2', 'endpoint3']
122+
123+
// Start all requests
124+
endpoints.forEach((endpoint, i) => {
125+
const req = createRequestEvent(
126+
String(i + 1),
127+
`https://api.example.com/${endpoint}`
128+
)
129+
capturer.handleNetworkRequestStarted(req as any)
130+
})
131+
132+
// Complete all requests
133+
endpoints.forEach((endpoint, i) => {
134+
const res = createResponseEvent(
135+
String(i + 1),
136+
`https://api.example.com/${endpoint}`,
137+
{ contentType: 'application/json', size: 1024 }
138+
)
139+
capturer.handleNetworkResponseCompleted(res as any)
140+
})
141+
142+
expect(capturer.networkRequests).toHaveLength(3)
143+
144+
// Verify all URLs
145+
const urls = capturer.networkRequests.map((r) => r.url)
146+
expect(urls).toEqual([
147+
'https://api.example.com/endpoint1',
148+
'https://api.example.com/endpoint2',
149+
'https://api.example.com/endpoint3'
150+
])
151+
152+
// Verify each request
153+
capturer.networkRequests.forEach((req, index) => {
154+
verifyRequest(req, {
155+
url: `https://api.example.com/endpoint${index + 1}`,
156+
method: 'GET',
157+
status: 200,
158+
contentType: 'application/json',
159+
size: 1024
160+
})
161+
})
162+
})
163+
})

0 commit comments

Comments
 (0)