Skip to content

Commit 223a255

Browse files
committed
test: cover network inspector initiator parsing
1 parent fe5d4c3 commit 223a255

1 file changed

Lines changed: 206 additions & 5 deletions

File tree

test/parallel/test-inspector-network-arbitrary-data.js

Lines changed: 206 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,51 @@ const { Network } = require('node:inspector');
99
const test = require('node:test');
1010
const assert = require('node:assert');
1111
const { waitUntil } = require('../common/inspector-helper');
12+
const { setImmediate: waitForTurn } = require('node:timers/promises');
1213

1314
const session = new inspector.Session();
1415
session.connect();
1516

17+
function createRequestPayload(overrides = {}) {
18+
return {
19+
requestId: '1',
20+
timestamp: 1,
21+
wallTime: 1,
22+
request: {
23+
url: 'https://example.com',
24+
method: 'GET',
25+
headers: {
26+
mKey: 'mValue',
27+
},
28+
},
29+
...overrides,
30+
};
31+
}
32+
33+
async function assertInvalidInitiatorStack(stack, requestId) {
34+
session.removeAllListeners();
35+
await session.post('Network.enable');
36+
37+
session.on('Network.requestWillBeSent', common.mustNotCall());
38+
39+
assert.throws(() => {
40+
Network.requestWillBeSent(createRequestPayload({
41+
requestId,
42+
initiator: {
43+
type: 'script',
44+
stack,
45+
},
46+
}));
47+
}, {
48+
name: 'TypeError',
49+
message: 'Invalid initiator.stack in event',
50+
});
51+
52+
await waitForTurn();
53+
}
54+
1655
test('should emit Network.requestWillBeSent with unicode', async () => {
56+
session.removeAllListeners();
1757
await session.post('Network.enable');
1858
const expectedValue = 'CJK 汉字 🍱 🧑‍🧑‍🧒‍🧒';
1959

@@ -24,18 +64,179 @@ test('should emit Network.requestWillBeSent with unicode', async () => {
2464
assert.strictEqual(event.params.request.headers.mKey, expectedValue);
2565
});
2666

27-
Network.requestWillBeSent({
28-
requestId: '1',
29-
timestamp: 1,
30-
wallTime: 1,
67+
Network.requestWillBeSent(createRequestPayload({
3168
request: {
3269
url: expectedValue,
3370
method: expectedValue,
3471
headers: {
3572
mKey: expectedValue,
3673
},
3774
},
38-
});
75+
}));
76+
77+
await requestWillBeSentFuture;
78+
});
79+
80+
test('should emit Network.requestWillBeSent with custom initiator', async () => {
81+
session.removeAllListeners();
82+
await session.post('Network.enable');
83+
84+
const requestWillBeSentFuture = waitUntil(session, 'Network.requestWillBeSent')
85+
.then(([event]) => {
86+
const { initiator } = event.params;
87+
assert.strictEqual(initiator.type, 'parser');
88+
assert.strictEqual(initiator.url, 'node:https://initiator.test/app.js');
89+
assert.strictEqual(initiator.lineNumber, 12);
90+
assert.strictEqual(initiator.columnNumber, 34);
91+
assert.strictEqual(initiator.requestId, 'parent-request-id');
92+
assert.strictEqual(initiator.stack.description, 'custom stack');
93+
assert.deepStrictEqual(initiator.stack.callFrames, [{
94+
functionName: 'run',
95+
scriptId: '99',
96+
url: 'file:///custom-frame.js',
97+
lineNumber: 3,
98+
columnNumber: 5,
99+
}]);
100+
assert.deepStrictEqual(initiator.stack.parent.callFrames, [{
101+
functionName: 'parentRun',
102+
scriptId: '100',
103+
url: 'file:///parent-frame.js',
104+
lineNumber: 8,
105+
columnNumber: 13,
106+
}]);
107+
assert.deepStrictEqual(initiator.stack.parentId, {
108+
id: 'async-stack-id',
109+
debuggerId: 'debugger-1',
110+
});
111+
});
112+
113+
Network.requestWillBeSent(createRequestPayload({
114+
requestId: 'custom-initiator-request',
115+
initiator: {
116+
type: 'parser',
117+
url: 'node:https://initiator.test/app.js',
118+
lineNumber: 12,
119+
columnNumber: 34,
120+
requestId: 'parent-request-id',
121+
stack: {
122+
description: 'custom stack',
123+
callFrames: [{
124+
functionName: 'run',
125+
scriptId: '99',
126+
url: 'file:///custom-frame.js',
127+
lineNumber: 3,
128+
columnNumber: 5,
129+
}],
130+
parent: {
131+
callFrames: [{
132+
functionName: 'parentRun',
133+
scriptId: '100',
134+
url: 'file:///parent-frame.js',
135+
lineNumber: 8,
136+
columnNumber: 13,
137+
}],
138+
extraNumber: 1.5,
139+
extraBoolean: true,
140+
extraNull: null,
141+
},
142+
parentId: {
143+
id: 'async-stack-id',
144+
debuggerId: 'debugger-1',
145+
},
146+
extraArray: ['frame', 1, false, null, { nested: 'value' }],
147+
},
148+
},
149+
}));
39150

40151
await requestWillBeSentFuture;
41152
});
153+
154+
test('should throw if initiator.type is missing', async () => {
155+
session.removeAllListeners();
156+
await session.post('Network.enable');
157+
158+
session.on('Network.requestWillBeSent', common.mustNotCall());
159+
160+
assert.throws(() => {
161+
Network.requestWillBeSent(createRequestPayload({
162+
requestId: 'missing-initiator-type',
163+
initiator: {
164+
stack: {
165+
callFrames: [],
166+
},
167+
},
168+
}));
169+
}, {
170+
name: 'TypeError',
171+
message: 'Missing initiator.type in event',
172+
});
173+
174+
await waitForTurn();
175+
});
176+
177+
test('should throw if initiator.stack is invalid', async () => {
178+
await assertInvalidInitiatorStack({
179+
callFrames: [],
180+
unsupportedValue: 1n,
181+
}, 'invalid-initiator-stack');
182+
});
183+
184+
test('should throw if initiator.stack contains an invalid array element',
185+
async () => {
186+
await assertInvalidInitiatorStack({
187+
callFrames: [],
188+
extraArray: [1n],
189+
}, 'invalid-initiator-stack-array-element');
190+
});
191+
192+
test('should throw if initiator.stack contains an array accessor that throws',
193+
async () => {
194+
const extraArray = [];
195+
Object.defineProperty(extraArray, 0, {
196+
enumerable: true,
197+
get() {
198+
throw new Error('array getter boom');
199+
},
200+
});
201+
extraArray.length = 1;
202+
203+
await assertInvalidInitiatorStack({
204+
callFrames: [],
205+
extraArray,
206+
}, 'invalid-initiator-stack-array-getter');
207+
});
208+
209+
test('should throw if initiator.stack has a property accessor that throws',
210+
async () => {
211+
const stack = { callFrames: [] };
212+
Object.defineProperty(stack, 'broken', {
213+
enumerable: true,
214+
get() {
215+
throw new Error('getter boom');
216+
},
217+
});
218+
219+
await assertInvalidInitiatorStack(
220+
stack,
221+
'invalid-initiator-stack-property-getter',
222+
);
223+
});
224+
225+
test('should throw if initiator.stack property enumeration throws', async () => {
226+
const stack = new Proxy({ callFrames: [] }, {
227+
ownKeys() {
228+
throw new Error('ownKeys boom');
229+
},
230+
getOwnPropertyDescriptor() {
231+
return {
232+
enumerable: true,
233+
configurable: true,
234+
};
235+
},
236+
});
237+
238+
await assertInvalidInitiatorStack(
239+
stack,
240+
'invalid-initiator-stack-own-keys',
241+
);
242+
});

0 commit comments

Comments
 (0)