UNPKG

2.79 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} = 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 console.assert(!this._recording, 'Cannot start recording trace while already recording trace.');
38 console.assert(options.path, 'Must specify a path to write trace file to.');
39
40 const defaultCategories = [
41 '-*', 'devtools.timeline', 'v8.execute', 'disabled-by-default-devtools.timeline',
42 'disabled-by-default-devtools.timeline.frame', 'toplevel',
43 'blink.console', 'blink.user_timing', 'latencyInfo', 'disabled-by-default-devtools.timeline.stack',
44 'disabled-by-default-v8.cpu_profiler'
45 ];
46 const categoriesArray = options.categories || defaultCategories;
47
48 if (options.screenshots)
49 categoriesArray.push('disabled-by-default-devtools.screenshot');
50
51 this._path = options.path;
52 this._recording = true;
53 await this._client.send('Tracing.start', {
54 transferMode: 'ReturnAsStream',
55 categories: categoriesArray.join(',')
56 });
57 }
58
59 async stop() {
60 let fulfill;
61 const contentPromise = new Promise(x => fulfill = x);
62 this._client.once('Tracing.tracingComplete', event => {
63 this._readStream(event.stream, this._path).then(fulfill);
64 });
65 await this._client.send('Tracing.end');
66 this._recording = false;
67 return contentPromise;
68 }
69
70 /**
71 * @param {string} handle
72 * @param {string} path
73 */
74 async _readStream(handle, path) {
75 let eof = false;
76 const file = await openAsync(path, 'w');
77 while (!eof) {
78 const response = await this._client.send('IO.read', {handle});
79 eof = response.eof;
80 if (path)
81 await writeAsync(file, response.data);
82 }
83 await closeAsync(file);
84 await this._client.send('IO.close', {handle});
85 }
86}
87helper.tracePublicAPI(Tracing);
88
89module.exports = Tracing;