@elastic/synthetics 1.0.0-beta.22 → 1.0.0-beta.25

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.
Files changed (81) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/NOTICE.txt +0 -29
  3. package/dist/cli.js +55 -184
  4. package/dist/cli.js.map +1 -1
  5. package/dist/common_types.d.ts +43 -36
  6. package/dist/common_types.d.ts.map +1 -1
  7. package/dist/core/gatherer.d.ts +2 -3
  8. package/dist/core/gatherer.d.ts.map +1 -1
  9. package/dist/core/gatherer.js +17 -9
  10. package/dist/core/gatherer.js.map +1 -1
  11. package/dist/core/index.d.ts +1 -1
  12. package/dist/core/index.d.ts.map +1 -1
  13. package/dist/core/index.js +7 -9
  14. package/dist/core/index.js.map +1 -1
  15. package/dist/core/runner.d.ts +1 -8
  16. package/dist/core/runner.d.ts.map +1 -1
  17. package/dist/core/runner.js +2 -3
  18. package/dist/core/runner.js.map +1 -1
  19. package/dist/dsl/journey.d.ts +4 -3
  20. package/dist/dsl/journey.d.ts.map +1 -1
  21. package/dist/dsl/journey.js +4 -3
  22. package/dist/dsl/journey.js.map +1 -1
  23. package/dist/dsl/step.d.ts +3 -2
  24. package/dist/dsl/step.d.ts.map +1 -1
  25. package/dist/dsl/step.js +2 -1
  26. package/dist/dsl/step.js.map +1 -1
  27. package/dist/formatter/javascript.d.ts +31 -6
  28. package/dist/formatter/javascript.d.ts.map +1 -1
  29. package/dist/formatter/javascript.js +45 -24
  30. package/dist/formatter/javascript.js.map +1 -1
  31. package/dist/helpers.d.ts +2 -1
  32. package/dist/helpers.d.ts.map +1 -1
  33. package/dist/helpers.js +30 -1
  34. package/dist/helpers.js.map +1 -1
  35. package/dist/index.d.ts +2 -2
  36. package/dist/index.d.ts.map +1 -1
  37. package/dist/index.js +1 -17
  38. package/dist/index.js.map +1 -1
  39. package/dist/{parse_args.d.ts → loader.d.ts} +2 -5
  40. package/dist/loader.d.ts.map +1 -0
  41. package/dist/loader.js +144 -0
  42. package/dist/loader.js.map +1 -0
  43. package/dist/options.d.ts +27 -0
  44. package/dist/options.d.ts.map +1 -0
  45. package/dist/options.js +108 -0
  46. package/dist/options.js.map +1 -0
  47. package/dist/plugins/network.d.ts +17 -33
  48. package/dist/plugins/network.d.ts.map +1 -1
  49. package/dist/plugins/network.js +179 -245
  50. package/dist/plugins/network.js.map +1 -1
  51. package/dist/plugins/plugin-manager.d.ts +1 -1
  52. package/dist/plugins/plugin-manager.d.ts.map +1 -1
  53. package/dist/plugins/plugin-manager.js +2 -2
  54. package/dist/plugins/plugin-manager.js.map +1 -1
  55. package/dist/reporters/json.d.ts +0 -1
  56. package/dist/reporters/json.d.ts.map +1 -1
  57. package/dist/reporters/json.js +5 -24
  58. package/dist/reporters/json.js.map +1 -1
  59. package/dist/sdk/trace-metrics.js +3 -4
  60. package/dist/sdk/trace-metrics.js.map +1 -1
  61. package/dist/tsconfig.tsbuildinfo +1 -1
  62. package/package.json +5 -4
  63. package/src/cli.ts +114 -188
  64. package/src/common_types.ts +47 -36
  65. package/src/core/gatherer.ts +17 -10
  66. package/src/core/index.ts +22 -16
  67. package/src/core/runner.ts +3 -23
  68. package/src/dsl/journey.ts +10 -4
  69. package/src/dsl/step.ts +9 -2
  70. package/src/formatter/javascript.ts +59 -22
  71. package/src/helpers.ts +40 -1
  72. package/src/index.ts +10 -16
  73. package/src/loader.ts +162 -0
  74. package/src/options.ts +116 -0
  75. package/src/plugins/network.ts +218 -293
  76. package/src/plugins/plugin-manager.ts +2 -2
  77. package/src/reporters/json.ts +1 -17
  78. package/dist/parse_args.d.ts.map +0 -1
  79. package/dist/parse_args.js +0 -103
  80. package/dist/parse_args.js.map +0 -1
  81. package/src/parse_args.ts +0 -158
@@ -23,359 +23,284 @@
23
23
  *
24
24
  */
25
25
 
26
- import { Protocol } from 'playwright-chromium/types/protocol';
26
+ import { Page, Request, Response } from 'playwright-chromium';
27
27
  import { NetworkInfo, BrowserInfo, Driver } from '../common_types';
28
28
  import { Step } from '../dsl';
29
29
  import { getTimestamp } from '../helpers';
30
30
 
31
+ /**
32
+ * Kibana UI expects the requestStartTime and loadEndTime to be baseline
33
+ * in seconds as they have the logic to convert it to milliseconds before
34
+ * using for offset calculation
35
+ */
36
+ function epochTimeInSeconds() {
37
+ return getTimestamp() / 1e6;
38
+ }
39
+
40
+ /**
41
+ * Used as a key in each Network Request to identify the
42
+ * associated request across distinct lifecycle events
43
+ */
44
+ export const NETWORK_ENTRY_SUMBOL = Symbol.for('NetworkEntry');
45
+
46
+ type RequestWithEntry = Request & {
47
+ NETWORK_ENTRY_SUMBOL?: symbol;
48
+ };
49
+
31
50
  export class NetworkManager {
32
51
  private _browser: BrowserInfo;
33
- private _InflightRequestMap = new Map<string, NetworkInfo>();
52
+ private _barrierPromises = new Set<Promise<void>>();
34
53
  results: Array<NetworkInfo> = [];
35
54
  _currentStep: Partial<Step> = null;
36
55
 
37
56
  constructor(private driver: Driver) {}
38
57
 
58
+ /**
59
+ * Adds a protection barrier aganist all asynchronous extract operations from
60
+ * request/response object that are happening during page lifecycle, If the
61
+ * page is closed during the extraction, the barrier enforces those operations
62
+ * to not result in exception
63
+ */
64
+ private _addBarrier(page: Page, promise: Promise<void>) {
65
+ if (!page) return;
66
+ const race = Promise.race([
67
+ new Promise<void>(resolve =>
68
+ page.on('close', () => {
69
+ this._barrierPromises.delete(race);
70
+ resolve();
71
+ })
72
+ ),
73
+ promise,
74
+ ]);
75
+ this._barrierPromises.add(race);
76
+ race.then(() => this._barrierPromises.delete(race));
77
+ }
78
+
39
79
  async start() {
40
- const { client } = this.driver;
80
+ const { client, context } = this.driver;
41
81
  const { product } = await client.send('Browser.getVersion');
42
82
  const [name, version] = product.split('/');
43
83
  this._browser = { name, version };
44
84
  await client.send('Network.enable');
45
85
  /**
46
- * Listen for all network events
86
+ * Listen for all network events from PW context
47
87
  */
48
- client.on(
49
- 'Network.requestWillBeSent',
50
- this._onRequestWillBeSent.bind(this)
51
- );
52
- client.on(
53
- 'Network.requestWillBeSentExtraInfo',
54
- this._onRequestWillBeSentExtraInfo.bind(this)
55
- );
56
- client.on('Network.dataReceived', this._onDataReceived.bind(this));
57
- client.on('Network.responseReceived', this._onResponseReceived.bind(this));
58
- client.on('Network.loadingFinished', this._onLoadingFinished.bind(this));
59
- client.on('Network.loadingFailed', this._onLoadingFailed.bind(this));
88
+ context.on('request', this._onRequest.bind(this));
89
+ context.on('response', this._onResponse.bind(this));
90
+ context.on('requestfinished', this._onRequestCompleted.bind(this));
91
+ context.on('requestfailed', this._onRequestCompleted.bind(this));
60
92
  }
61
93
 
62
- _findNetworkRecord(requestId: string) {
63
- return this._InflightRequestMap.get(requestId);
94
+ private _findNetworkEntry(
95
+ request: RequestWithEntry
96
+ ): NetworkInfo | undefined {
97
+ return request[NETWORK_ENTRY_SUMBOL];
64
98
  }
65
99
 
66
- _onRequestWillBeSent(event: Protocol.Network.requestWillBeSentPayload) {
67
- const { url, method, postData, headers } = event.request;
100
+ private _onRequest(request: Request) {
101
+ const url = request.url();
68
102
  /**
69
103
  * Data URI should not show up as network requests
70
104
  */
71
105
  if (url.startsWith('data:')) {
72
106
  return;
73
107
  }
74
- const { requestId, timestamp, type, loaderId } = event;
75
- const isNavigationRequest = requestId == loaderId && type === 'Document';
76
- const record = this._findNetworkRecord(requestId);
77
- /**
78
- * On redirects, another `requestWillBeSent` event will be fired for the
79
- * same requestId. We calculate the timings for the redirect request using
80
- * the `redirectedResponse` from the redirected request.
81
- */
82
- if (record) {
83
- if (event.redirectResponse) {
84
- record.response.redirectURL = url;
85
- const response = event.redirectResponse;
86
- const data = Object.assign(event, {
87
- type: event.type,
88
- response,
89
- encodedDataLength: response.encodedDataLength,
90
- });
91
- this._onResponseReceived(data);
92
- this._onLoadingFinished(data);
93
- } else {
94
- /**
95
- * Edge case, we handle it to proceed with next navigation
96
- */
97
- this._onLoadingFailed(
98
- Object.assign(event, {
99
- type: event.type,
100
- errorText: 'redirectResponse data is not available',
101
- })
102
- );
103
- }
104
- const redirectedRecord = this._findNetworkRecord(requestId);
105
- /**
106
- * Rewrite the map with new redirect id to not reset
107
- * the redirect request with original request
108
- */
109
- this._InflightRequestMap.delete(requestId);
110
- this._InflightRequestMap.set(
111
- `redirect:${timestamp}:${requestId}`,
112
- redirectedRecord
113
- );
114
- }
115
108
 
116
- this._InflightRequestMap.set(requestId, {
109
+ const timestamp = getTimestamp();
110
+ const networkEntry: NetworkInfo = {
117
111
  browser: this._browser,
118
112
  step: this._currentStep,
119
- timestamp: getTimestamp(),
113
+ timestamp,
120
114
  url,
121
- type,
115
+ type: request.resourceType(),
122
116
  request: {
123
117
  url,
124
- method,
125
- headers,
126
- bytes: postData?.length || 0,
118
+ method: request.method(),
119
+ headers: {},
120
+ body: {
121
+ bytes: request.postDataBuffer()?.length || 0,
122
+ },
127
123
  },
128
124
  response: {
129
125
  status: -1,
130
- mimeType: 'x-unknown',
131
126
  headers: {},
132
- timing: null,
127
+ mimeType: 'x-unknown',
128
+ redirectURL: '',
133
129
  },
134
- isNavigationRequest,
135
- requestSentTime: timestamp,
136
- responseReceivedTime: -1,
130
+ isNavigationRequest: request.isNavigationRequest(),
131
+ requestSentTime: epochTimeInSeconds(),
137
132
  loadEndTime: -1,
133
+ responseReceivedTime: -1,
138
134
  resourceSize: 0,
139
135
  transferSize: 0,
140
136
  timings: null,
141
- });
142
- }
143
-
144
- _onRequestWillBeSentExtraInfo(
145
- event: Protocol.Network.requestWillBeSentExtraInfoPayload
146
- ) {
147
- const { requestId, headers } = event;
148
- const record = this._findNetworkRecord(requestId);
149
- if (!record) {
150
- return;
151
- }
152
- /**
153
- * Enhance request headers with additional information
154
- */
155
- record.request.headers = {
156
- ...record.request.headers,
157
- ...headers,
158
137
  };
159
- record.request.referrer = record.request.headers?.Referer;
160
- }
161
-
162
- _onDataReceived(event: Protocol.Network.dataReceivedPayload) {
163
- const { requestId, dataLength, encodedDataLength } = event;
164
- const record = this._findNetworkRecord(requestId);
165
- if (!record) {
166
- return;
167
- }
168
- record.resourceSize += dataLength;
169
- if (encodedDataLength >= 0) record.transferSize += encodedDataLength;
170
- }
171
138
 
172
- _onResponseReceived(event: Protocol.Network.responseReceivedPayload) {
173
- const { requestId, response, timestamp } = event;
174
- const record = this._findNetworkRecord(requestId);
175
- if (!record) {
176
- return;
139
+ if (request.redirectedFrom()) {
140
+ const fromEntry = this._findNetworkEntry(request.redirectedFrom());
141
+ if (fromEntry) fromEntry.response.redirectURL = request.url();
177
142
  }
178
143
 
179
- record.responseReceivedTime = timestamp;
180
- record.transferSize = response.encodedDataLength;
181
- record.response = {
182
- url: response.url,
183
- status: response.status,
184
- protocol: response.protocol,
185
- statusText: response.statusText,
186
- headers: response.headers,
187
- mimeType: response.mimeType,
188
- remoteIPAddress: response.remoteIPAddress,
189
- remotePort: response.remotePort,
190
- fromServiceWorker: response.fromServiceWorker,
191
- redirectURL: record.response.redirectURL,
192
- timing: response.timing,
193
- };
194
- if (response.securityDetails) {
195
- record.response.securityDetails = {
196
- protocol: response.securityDetails.protocol,
197
- subjectName: response.securityDetails.subjectName,
198
- issuer: response.securityDetails.issuer,
199
- validFrom: response.securityDetails.validFrom,
200
- validTo: response.securityDetails.validTo,
201
- };
202
- }
203
- }
204
-
205
- _onLoadingFinished(event: Protocol.Network.loadingFinishedPayload) {
206
- const { requestId, timestamp, encodedDataLength } = event;
207
- this._requestCompleted(requestId, timestamp, encodedDataLength);
144
+ request[NETWORK_ENTRY_SUMBOL] = networkEntry;
145
+ this.results.push(networkEntry);
208
146
  }
209
147
 
210
- _onLoadingFailed(event: Protocol.Network.loadingFailedPayload) {
211
- const { requestId, timestamp } = event;
212
- this._requestCompleted(requestId, timestamp);
213
- }
148
+ private async _onResponse(response: Response) {
149
+ const request = response.request();
150
+ const networkEntry = this._findNetworkEntry(request);
151
+ if (!networkEntry) return;
214
152
 
215
- _requestCompleted(
216
- requestId: string,
217
- endTime: number,
218
- encodedDataLength?: number
219
- ) {
220
- const record = this._findNetworkRecord(requestId);
221
- if (!record) {
222
- return;
223
- }
224
- if (encodedDataLength >= 0) {
225
- record.transferSize = encodedDataLength;
226
- record.response.body = {
227
- bytes: encodedDataLength,
228
- };
229
- }
230
- record.loadEndTime = endTime;
231
- record.timings = calculateTimings(record);
232
- this.results.push(record);
233
- /**
234
- * When there is DNS failure, browsers keeps retrying requests which
235
- * might result in incorrect timings so we get remove them to measure only once
236
- */
237
- this._InflightRequestMap.delete(requestId);
238
- }
153
+ networkEntry.responseReceivedTime = epochTimeInSeconds();
154
+ networkEntry.response = {
155
+ url: response.url(),
156
+ status: response.status(),
157
+ statusText: response.statusText(),
158
+ headers: {},
159
+ mimeType: 'x-unknown',
160
+ redirectURL: networkEntry.response.redirectURL,
161
+ };
239
162
 
240
- /**
241
- * Account for missing response received event and also adjust the
242
- * response received event based on when first byte event was recorded
243
- */
163
+ const page = request.frame().page();
164
+ this._addBarrier(
165
+ page,
166
+ request.allHeaders().then(reqHeaders => {
167
+ networkEntry.request.headers = reqHeaders;
168
+ networkEntry.request.referrer = reqHeaders?.referer;
169
+ })
170
+ );
171
+ this._addBarrier(
172
+ page,
173
+ response.serverAddr().then(server => {
174
+ networkEntry.response.remoteIPAddress = server?.ipAddress;
175
+ networkEntry.response.remotePort = server?.port;
176
+ })
177
+ );
178
+ this._addBarrier(
179
+ page,
180
+ response.securityDetails().then(details => {
181
+ if (details) networkEntry.response.securityDetails = details;
182
+ })
183
+ );
184
+ this._addBarrier(
185
+ page,
186
+ response.allHeaders().then(resHeaders => {
187
+ networkEntry.response.headers = resHeaders;
244
188
 
245
- stop() {
246
- return this.results;
189
+ const contentType = resHeaders['content-type'];
190
+ if (contentType)
191
+ networkEntry.response.mimeType = contentType.split(';')[0];
192
+ })
193
+ );
247
194
  }
248
- }
249
195
 
250
- function getResponseReceivedTime(
251
- timing: Protocol.Network.Response['timing'],
252
- responseReceivedTime: number
253
- ) {
254
- if (timing == null) {
255
- return responseReceivedTime;
256
- }
257
- const startTime = timing.requestTime;
258
- const headersReceivedTime = startTime + timing.receiveHeadersEnd / 1000;
259
- if (responseReceivedTime < 0 || responseReceivedTime > headersReceivedTime) {
260
- responseReceivedTime = headersReceivedTime;
261
- }
262
- if (startTime > responseReceivedTime) {
263
- responseReceivedTime = startTime;
264
- }
265
- return responseReceivedTime;
266
- }
196
+ private async _onRequestCompleted(request: Request) {
197
+ const networkEntry = this._findNetworkEntry(request);
198
+ if (!networkEntry) return;
267
199
 
268
- /**
269
- * The timing calculations are based on the chrome devtools frontend
270
- * https://github.com/ChromeDevTools/devtools-frontend/blob/7f5478d8ceb7586f23f4073ab5c2085dac1ec26a/front_end/network/RequestTimingView.js#L98-L193
271
- */
272
- export function calculateTimings(record: NetworkInfo) {
273
- const result: NetworkInfo['timings'] = {
274
- blocked: -1,
275
- queueing: -1,
276
- proxy: -1,
277
- dns: -1,
278
- ssl: -1,
279
- connect: -1,
280
- send: -1,
281
- wait: -1,
282
- receive: -1,
283
- total: -1,
284
- };
200
+ networkEntry.loadEndTime = epochTimeInSeconds();
201
+ const timing = request.timing();
202
+ const { loadEndTime, requestSentTime } = networkEntry;
203
+ networkEntry.timings = {
204
+ blocked: -1,
205
+ dns: -1,
206
+ ssl: -1,
207
+ connect: -1,
208
+ send: -1,
209
+ wait: -1,
210
+ receive: -1,
211
+ total: -1,
212
+ };
285
213
 
286
- const toMilliseconds = (time: number) => (time === -1 ? -1 : time * 1000);
287
- const calculateDiffInMs = (
288
- name: keyof NetworkInfo['timings'],
289
- start: number,
290
- end: number
291
- ) => {
292
- if (start < Number.MAX_VALUE && start <= end) {
293
- result[name] = toMilliseconds(end - start);
294
- }
295
- };
296
- const firstPositive = (numbers: number[]) => {
297
- for (let i = 0; i < numbers.length; ++i) {
298
- if (numbers[i] > 0) {
299
- return numbers[i];
214
+ const firstPositive = (numbers: number[]) => {
215
+ for (let i = 0; i < numbers.length; ++i) {
216
+ if (numbers[i] > 0) {
217
+ return numbers[i];
218
+ }
300
219
  }
301
- }
302
- return null;
303
- };
304
- /**
305
- * requestTime is baseline in seconds, rest of the timing data are ticks in milliseconds
306
- * from the requestTime, so we calculate the offset from that
307
- */
308
- const addOffsetRange = (
309
- name: keyof NetworkInfo['timings'],
310
- start: number,
311
- end: number
312
- ) => {
313
- if (start >= 0 && end >= 0) {
314
- calculateDiffInMs(name, startTime + start / 1000, startTime + end / 1000);
315
- }
316
- };
317
- const { requestSentTime, loadEndTime, responseReceivedTime, response } =
318
- record;
319
- const timing = response.timing;
320
- const actResRcvdTime = getResponseReceivedTime(timing, responseReceivedTime);
321
- const issueTime = requestSentTime;
322
- const startTime = timing == null ? -1 : timing.requestTime;
323
- const endTime = firstPositive([loadEndTime, actResRcvdTime]) || startTime;
220
+ return null;
221
+ };
222
+ const roundMilliSecs = (value: number): number => {
223
+ return Math.floor(value * 1000) / 1000;
224
+ };
324
225
 
325
- if (timing == null) {
326
- const start =
327
- issueTime !== -1 ? issueTime : startTime !== -1 ? startTime : 0;
328
- const middle = actResRcvdTime === -1 ? Number.MAX_VALUE : actResRcvdTime;
329
- const end = endTime === -1 ? Number.MAX_VALUE : endTime;
330
- calculateDiffInMs('total', start, end);
331
- calculateDiffInMs('blocked', start, middle);
332
- calculateDiffInMs('receive', middle, end);
333
- // Check if the request is blocked/stalled for the whole timeframe and
334
- // calculate timings appropriately for that request
335
- if (!isFinite(result['blocked'])) {
336
- result['blocked'] = result['total'];
226
+ if (timing.startTime === 0) {
227
+ // Convert to milliseconds before round off
228
+ const total = roundMilliSecs((loadEndTime - requestSentTime) * 1000);
229
+ networkEntry.timings.total = total;
230
+ return;
337
231
  }
338
- return result;
339
- }
340
- calculateDiffInMs(
341
- 'total',
342
- issueTime < startTime ? issueTime : startTime,
343
- endTime
344
- );
345
- if (issueTime < startTime) {
346
- calculateDiffInMs('queueing', issueTime, startTime);
347
- }
348
- const responseReceived = toMilliseconds(actResRcvdTime - startTime);
349
232
 
350
- if (response.fromServiceWorker) {
351
- addOffsetRange('blocked', 0, timing.workerStart);
352
- addOffsetRange('wait', timing.sendEnd, responseReceived);
353
- } else if (!timing.pushStart) {
354
- const blockingEnd =
355
- firstPositive([
356
- timing.dnsStart,
357
- timing.connectStart,
358
- timing.sendStart,
359
- responseReceived,
360
- ]) || 0;
361
- addOffsetRange('blocked', 0, blockingEnd);
362
- addOffsetRange('proxy', timing.proxyStart, timing.proxyEnd);
363
- addOffsetRange('dns', timing.dnsStart, timing.dnsEnd);
364
- addOffsetRange('connect', timing.connectStart, timing.connectEnd);
365
- addOffsetRange('ssl', timing.sslStart, timing.sslEnd);
366
- addOffsetRange('send', timing.sendStart, timing.sendEnd);
367
- addOffsetRange(
368
- 'wait',
369
- Math.max(
370
- timing.sendEnd,
371
- timing.connectEnd,
372
- timing.dnsEnd,
373
- timing.proxyEnd,
374
- blockingEnd
375
- ),
376
- responseReceived
233
+ const blocked =
234
+ roundMilliSecs(
235
+ firstPositive([
236
+ timing.domainLookupStart,
237
+ timing.connectStart,
238
+ timing.requestStart,
239
+ ])
240
+ ) || -1;
241
+ const dns =
242
+ timing.domainLookupEnd !== -1
243
+ ? roundMilliSecs(timing.domainLookupEnd - timing.domainLookupStart)
244
+ : -1;
245
+ const connect =
246
+ timing.connectEnd !== -1
247
+ ? roundMilliSecs(timing.connectEnd - timing.connectStart)
248
+ : -1;
249
+ const ssl =
250
+ timing.secureConnectionStart !== -1
251
+ ? roundMilliSecs(timing.connectEnd - timing.secureConnectionStart)
252
+ : -1;
253
+ const wait =
254
+ timing.responseStart !== -1
255
+ ? roundMilliSecs(timing.responseStart - timing.requestStart)
256
+ : -1;
257
+ const receive =
258
+ timing.responseEnd !== -1
259
+ ? roundMilliSecs(timing.responseEnd - timing.responseStart)
260
+ : -1;
261
+ const total = [blocked, dns, connect, wait, receive].reduce(
262
+ (pre, cur) => (cur > 0 ? cur + pre : pre),
263
+ 0
264
+ );
265
+ networkEntry.timings = {
266
+ blocked,
267
+ dns,
268
+ connect,
269
+ ssl,
270
+ wait,
271
+ send: 0, // not exposed via RT api
272
+ receive,
273
+ total,
274
+ };
275
+
276
+ const page = request.frame().page();
277
+ // For aborted/failed requests sizes will not be present
278
+ this._addBarrier(
279
+ page,
280
+ request.sizes().then(sizes => {
281
+ networkEntry.request.bytes =
282
+ sizes.requestHeadersSize + sizes.requestBodySize;
283
+ networkEntry.request.body = {
284
+ bytes: sizes.requestBodySize,
285
+ };
286
+ networkEntry.response.bytes =
287
+ sizes.responseHeadersSize + sizes.responseBodySize;
288
+ networkEntry.response.body = {
289
+ bytes: sizes.responseBodySize,
290
+ };
291
+ networkEntry.transferSize = sizes.responseBodySize;
292
+ })
377
293
  );
378
294
  }
379
- calculateDiffInMs('receive', actResRcvdTime, endTime);
380
- return result;
295
+
296
+ async stop() {
297
+ await Promise.all(this._barrierPromises);
298
+ const context = this.driver.context;
299
+ context.off('request', this._onRequest.bind(this));
300
+ context.off('response', this._onResponse.bind(this));
301
+ context.off('requestfinished', this._onRequestCompleted.bind(this));
302
+ context.off('requestfailed', this._onRequestCompleted.bind(this));
303
+ this._barrierPromises.clear();
304
+ return this.results;
305
+ }
381
306
  }
@@ -102,11 +102,11 @@ export class PluginManager {
102
102
  (this.get('network') as NetworkManager)._currentStep = step;
103
103
  }
104
104
 
105
- output() {
105
+ async output() {
106
106
  const data: PluginOutput = {};
107
107
  for (const [, plugin] of this.plugins) {
108
108
  if (plugin instanceof NetworkManager) {
109
- data.networkinfo = plugin.stop();
109
+ data.networkinfo = await plugin.stop();
110
110
  } else if (plugin instanceof BrowserConsole) {
111
111
  data.browserconsole = plugin.stop();
112
112
  }
@@ -128,23 +128,8 @@ function getMetadata() {
128
128
  };
129
129
  }
130
130
 
131
- function formatVersion(protocol: string | undefined) {
132
- if (!protocol) {
133
- return;
134
- }
135
- if (protocol === 'h2') {
136
- return 2;
137
- } else if (protocol === 'http/1.1') {
138
- return 1.1;
139
- } else if (protocol === 'http/1.0') {
140
- return 1.0;
141
- } else if (protocol.startsWith('h3')) {
142
- return 3;
143
- }
144
- }
145
-
146
131
  function formatTLS(tls: SecurityDetails) {
147
- if (!tls) {
132
+ if (!tls || !tls.protocol) {
148
133
  return;
149
134
  }
150
135
  const [name, version] = tls.protocol.toLowerCase().split(' ');
@@ -177,7 +162,6 @@ export function formatNetworkFields(network: NetworkInfo) {
177
162
  original: request.headers?.['User-Agent'],
178
163
  },
179
164
  http: {
180
- version: formatVersion(response?.protocol),
181
165
  request,
182
166
  response,
183
167
  },
@@ -1 +0,0 @@
1
- {"version":3,"file":"parse_args.d.ts","sourceRoot":"","sources":["../src/parse_args.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAGH,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAuFzC,QAAA,MAAM,OAAO,6BAA8B,CAAC;AAC5C,QAAA,MAAM,OAAO,SAA4B,CAAC;AA0C1C,OAAO,EAAE,OAAO,EAAE,CAAC;AACnB,eAAe,OAAO,CAAC"}