UNPKG

2.99 kBJavaScriptView Raw
1/**
2 * Copyright 2017 Google Inc. All rights reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16const {helper, assert} = require('./helper');
17const fs = require('fs');
18
19const openAsync = helper.promisify(fs.open);
20const writeAsync = helper.promisify(fs.write);
21const closeAsync = helper.promisify(fs.close);
22
23class Tracing {
24 /**
25 * @param {!Puppeteer.CDPSession} client
26 */
27 constructor(client) {
28 this._client = client;
29 this._recording = false;
30 this._path = '';
31 }
32
33 /**
34 * @param {!Object} options
35 */
36 async start(options) {
37 assert(!this._recording, 'Cannot start recording trace while already recording trace.');
38
39 const defaultCategories = [
40 '-*', 'devtools.timeline', 'v8.execute', 'disabled-by-default-devtools.timeline',
41 'disabled-by-default-devtools.timeline.frame', 'toplevel',
42 'blink.console', 'blink.user_timing', 'latencyInfo', 'disabled-by-default-devtools.timeline.stack',
43 'disabled-by-default-v8.cpu_profiler', 'disabled-by-default-v8.cpu_profiler.hires'
44 ];
45 const categoriesArray = options.categories || defaultCategories;
46
47 if (options.screenshots)
48 categoriesArray.push('disabled-by-default-devtools.screenshot');
49
50 this._path = options.path;
51 this._recording = true;
52 await this._client.send('Tracing.start', {
53 transferMode: 'ReturnAsStream',
54 categories: categoriesArray.join(',')
55 });
56 }
57
58 async stop() {
59 let fulfill;
60 const contentPromise = new Promise(x => fulfill = x);
61 this._client.once('Tracing.tracingComplete', event => {
62 this._readStream(event.stream, this._path).then(fulfill);
63 });
64 await this._client.send('Tracing.end');
65 this._recording = false;
66 return contentPromise;
67 }
68
69 /**
70 * @param {string} handle
71 * @param {string} path
72 */
73 async _readStream(handle, path) {
74 let eof = false;
75 let file;
76 if (path)
77 file = await openAsync(path, 'w');
78 const bufs = [];
79 while (!eof) {
80 const response = await this._client.send('IO.read', {handle});
81 eof = response.eof;
82 bufs.push(Buffer.from(response.data));
83 if (path)
84 await writeAsync(file, response.data);
85 }
86 if (path)
87 await closeAsync(file);
88 await this._client.send('IO.close', {handle});
89 let resultBuffer = null;
90 try {
91 resultBuffer = Buffer.concat(bufs);
92 } finally {
93 return resultBuffer;
94 }
95 }
96}
97helper.tracePublicAPI(Tracing);
98
99module.exports = Tracing;