From 98bb2615adb6815c91efcc59593b49e2ec8c3935 Mon Sep 17 00:00:00 2001 From: Yaniv Efraim Date: Thu, 12 Apr 2018 18:26:50 +0300 Subject: [PATCH] feat(Tracing): return a buffer from tracing.stop (#2360) Fixes #2148 --- docs/api.md | 4 ++-- lib/Tracing.js | 16 +++++++++++++--- test/tracing.spec.js | 30 ++++++++++++++++++++++++++++-- 3 files changed, 43 insertions(+), 7 deletions(-) diff --git a/docs/api.md b/docs/api.md index 7ce22aadd086d..4f206b8826866 100644 --- a/docs/api.md +++ b/docs/api.md @@ -1602,7 +1602,7 @@ await page.tracing.stop(); #### tracing.start(options) - `options` <[Object]> - - `path` <[string]> A path to write the trace file to. **required** + - `path` <[string]> A path to write the trace file to. - `screenshots` <[boolean]> captures screenshots in the trace. - `categories` <[Array]<[string]>> specify custom categories to use instead of default. - returns: <[Promise]> @@ -1610,7 +1610,7 @@ await page.tracing.stop(); Only one trace can be active at a time per browser. #### tracing.stop() -- returns: <[Promise]> +- returns: <[Promise]<[Buffer]>> Promise which resolves to buffer with trace data. ### class: Dialog diff --git a/lib/Tracing.js b/lib/Tracing.js index 6b9a87e55a49e..1bce240b9b8fb 100644 --- a/lib/Tracing.js +++ b/lib/Tracing.js @@ -35,7 +35,6 @@ class Tracing { */ async start(options) { console.assert(!this._recording, 'Cannot start recording trace while already recording trace.'); - console.assert(options.path, 'Must specify a path to write trace file to.'); const defaultCategories = [ '-*', 'devtools.timeline', 'v8.execute', 'disabled-by-default-devtools.timeline', @@ -73,15 +72,26 @@ class Tracing { */ async _readStream(handle, path) { let eof = false; - const file = await openAsync(path, 'w'); + let file; + if (path) + file = await openAsync(path, 'w'); + const bufs = []; while (!eof) { const response = await this._client.send('IO.read', {handle}); eof = response.eof; + bufs.push(new Buffer(response.data)); if (path) await writeAsync(file, response.data); } - await closeAsync(file); + if (path) + await closeAsync(file); await this._client.send('IO.close', {handle}); + let resultBuffer = null; + try { + resultBuffer = Buffer.concat(bufs); + } finally { + return resultBuffer; + } } } helper.tracePublicAPI(Tracing); diff --git a/test/tracing.spec.js b/test/tracing.spec.js index f41091110afee..00ccc7d6678fe 100644 --- a/test/tracing.spec.js +++ b/test/tracing.spec.js @@ -27,8 +27,10 @@ module.exports.addTests = function({testRunner, expect}) { state.outputFile = path.join(__dirname, 'assets', `trace-${state.parallelIndex}.json`); }); afterEach(function(state) { - fs.unlinkSync(state.outputFile); - state.outputFile = null; + if (fs.existsSync(state.outputFile)) { + fs.unlinkSync(state.outputFile); + state.outputFile = null; + } }); it('should output a trace', async({page, server, outputFile}) => { await page.tracing.start({screenshots: true, path: outputFile}); @@ -52,5 +54,29 @@ module.exports.addTests = function({testRunner, expect}) { expect(error).toBeTruthy(); await page.tracing.stop(); }); + it('should return a buffer', async({page, server, outputFile}) => { + await page.tracing.start({screenshots: true, path: outputFile}); + await page.goto(server.PREFIX + '/grid.html'); + const trace = await page.tracing.stop(); + const buf = fs.readFileSync(outputFile); + expect(trace.toString()).toEqual(buf.toString()); + }); + it('should return null in case of Buffer error', async({page, server}) => { + await page.tracing.start({screenshots: true}); + await page.goto(server.PREFIX + '/grid.html'); + const oldBufferConcat = Buffer.concat; + Buffer.concat = bufs => { + throw 'error'; + }; + const trace = await page.tracing.stop(); + expect(trace).toEqual(null); + Buffer.concat = oldBufferConcat; + }); + it('should support a buffer without a path', async({page, server}) => { + await page.tracing.start({screenshots: true}); + await page.goto(server.PREFIX + '/grid.html'); + const trace = await page.tracing.stop(); + expect(trace.toString()).toContain('screenshot'); + }); }); };