PR-URL: https://github.com/nodejs/node/pull/61139 Reviewed-By: Chengzhong Wu <legendecas@gmail.com> Reviewed-By: Kohei Ueno <kohei.ueno119@gmail.com>
201 lines
5.2 KiB
JavaScript
201 lines
5.2 KiB
JavaScript
// Flags: --inspect=0 --experimental-network-inspection --experimental-storage-inspection
|
|
'use strict';
|
|
const common = require('../common');
|
|
|
|
common.skipIfInspectorDisabled();
|
|
|
|
const inspector = require('node:inspector/promises');
|
|
const assert = require('node:assert');
|
|
|
|
const EXPECTED_EVENTS = {
|
|
Network: [
|
|
{
|
|
name: 'requestWillBeSent',
|
|
params: {
|
|
requestId: 'request-id-1',
|
|
request: {
|
|
url: 'https://nodejs.org/en',
|
|
method: 'GET',
|
|
headers: {},
|
|
},
|
|
timestamp: 1000,
|
|
wallTime: 1000,
|
|
},
|
|
expected: {
|
|
requestId: 'request-id-1',
|
|
request: {
|
|
url: 'https://nodejs.org/en',
|
|
method: 'GET',
|
|
headers: {},
|
|
hasPostData: false,
|
|
},
|
|
timestamp: 1000,
|
|
wallTime: 1000,
|
|
}
|
|
},
|
|
{
|
|
name: 'responseReceived',
|
|
params: {
|
|
requestId: 'request-id-1',
|
|
timestamp: 1000,
|
|
type: 'Other',
|
|
response: {
|
|
url: 'https://nodejs.org/en',
|
|
status: 200,
|
|
statusText: '',
|
|
headers: { host: 'nodejs.org' },
|
|
mimeType: 'text/html',
|
|
charset: 'utf-8'
|
|
}
|
|
},
|
|
expected: {
|
|
requestId: 'request-id-1',
|
|
timestamp: 1000,
|
|
type: 'Other',
|
|
response: {
|
|
url: 'https://nodejs.org/en',
|
|
status: 200,
|
|
statusText: '',
|
|
headers: { host: 'nodejs.org' },
|
|
mimeType: 'text/html',
|
|
charset: 'utf-8'
|
|
}
|
|
}
|
|
},
|
|
{
|
|
name: 'dataReceived',
|
|
// Network.dataReceived is buffered until Network.streamResourceContent/Network.getResponseBody is invoked.
|
|
skip: true,
|
|
},
|
|
{
|
|
name: 'dataSent',
|
|
// Network.dataSent is buffered until Network.getRequestPostData is invoked.
|
|
skip: true,
|
|
},
|
|
{
|
|
name: 'loadingFinished',
|
|
params: {
|
|
requestId: 'request-id-1',
|
|
timestamp: 1000,
|
|
}
|
|
},
|
|
{
|
|
name: 'loadingFailed',
|
|
params: {
|
|
requestId: 'request-id-1',
|
|
timestamp: 1000,
|
|
type: 'Document',
|
|
errorText: 'Failed to load resource'
|
|
}
|
|
},
|
|
{
|
|
name: 'webSocketCreated',
|
|
params: {
|
|
requestId: 'websocket-id-1',
|
|
url: 'ws://example.com:8080',
|
|
}
|
|
|
|
},
|
|
{
|
|
name: 'webSocketHandshakeResponseReceived',
|
|
params: {
|
|
requestId: 'websocket-id-1',
|
|
response: {
|
|
status: 101,
|
|
statusText: 'Switching Protocols',
|
|
headers: {},
|
|
},
|
|
timestamp: 1000,
|
|
}
|
|
},
|
|
{
|
|
name: 'webSocketClosed',
|
|
params: {
|
|
requestId: 'websocket-id-1',
|
|
timestamp: 1000,
|
|
|
|
}
|
|
},
|
|
],
|
|
DOMStorage: [
|
|
{
|
|
name: 'domStorageItemAdded',
|
|
params: {
|
|
storageId: {
|
|
securityOrigin: '',
|
|
isLocalStorage: true,
|
|
storageKey: 'node-inspector://default-dom-storage',
|
|
},
|
|
key: 'testKey',
|
|
newValue: 'testValue',
|
|
}
|
|
},
|
|
{
|
|
name: 'domStorageItemRemoved',
|
|
skip: true
|
|
},
|
|
{
|
|
name: 'domStorageItemUpdated',
|
|
skip: true
|
|
},
|
|
{
|
|
name: 'domStorageItemsCleared',
|
|
skip: true
|
|
},
|
|
{
|
|
name: 'registerStorage',
|
|
skip: true
|
|
},
|
|
]
|
|
};
|
|
|
|
// Check that all domains and events are present in the inspector object.
|
|
for (const [domain, events] of Object.entries(EXPECTED_EVENTS)) {
|
|
if (!(domain in inspector)) {
|
|
assert.fail(`Expected domain ${domain} to be present in inspector`);
|
|
}
|
|
const actualEventNames = Object.keys(inspector[domain]).sort();
|
|
const expectedEventNames = events.map((event) => event.name).sort();
|
|
assert.deepStrictEqual(actualEventNames, expectedEventNames, `Expected ${domain} to have events ${expectedEventNames}, but got ${actualEventNames}`);
|
|
}
|
|
|
|
// Check that all events throw when called with a non-object argument.
|
|
for (const [domain, events] of Object.entries(EXPECTED_EVENTS)) {
|
|
for (const event of events) {
|
|
assert.throws(() => inspector[domain][event.name]('params'), {
|
|
name: 'TypeError',
|
|
code: 'ERR_INVALID_ARG_TYPE',
|
|
message: 'The "params" argument must be of type object. Received type string (\'params\')'
|
|
});
|
|
}
|
|
}
|
|
|
|
(async () => {
|
|
const session = new inspector.Session();
|
|
session.connect();
|
|
|
|
// Check that all events emit the expected parameters.
|
|
await session.post('Network.enable');
|
|
await session.post('DOMStorage.enable');
|
|
for (const [domain, events] of Object.entries(EXPECTED_EVENTS)) {
|
|
for (const event of events) {
|
|
if (event.skip) {
|
|
continue;
|
|
}
|
|
session.on(`${domain}.${event.name}`, common.mustCall(({ params }) => {
|
|
if (event.name === 'requestWillBeSent' || event.name === 'webSocketCreated') {
|
|
// Initiator is automatically captured and contains caller info.
|
|
// No need to validate it.
|
|
delete params.initiator;
|
|
}
|
|
assert.deepStrictEqual(params, event.expected ?? event.params);
|
|
}));
|
|
inspector[domain][event.name](event.params);
|
|
}
|
|
}
|
|
|
|
// Check tht no events are emitted after disabling the domain.
|
|
await session.post('Network.disable');
|
|
session.on('Network.requestWillBeSent', common.mustNotCall());
|
|
inspector.Network.requestWillBeSent({});
|
|
})().then(common.mustCall());
|