Fix racy condition in case of multiple parallel screenshots
Page.screenshot operates the global state of the page. In case of multiple Page.screenshot() commands running in parallel with different clipping rects, they interfere with each other. This patch makes Page.screenshot() commands run sequencially even though they were called in parallel. Fixes #15.
This commit is contained in:
parent
3b0bc0802d
commit
dbb374d4af
12
lib/Page.js
12
lib/Page.js
@ -56,6 +56,8 @@ class Page extends EventEmitter {
|
|||||||
/** @type {?function(!Request)} */
|
/** @type {?function(!Request)} */
|
||||||
this._requestInterceptor = null;
|
this._requestInterceptor = null;
|
||||||
|
|
||||||
|
this._screenshotTaskChain = Promise.resolve();
|
||||||
|
|
||||||
client.on('Debugger.paused', event => this._onDebuggerPaused(event));
|
client.on('Debugger.paused', event => this._onDebuggerPaused(event));
|
||||||
client.on('Debugger.scriptParsed', event => this._onScriptParsed(event));
|
client.on('Debugger.scriptParsed', event => this._onScriptParsed(event));
|
||||||
client.on('Network.responseReceived', event => this.emit(Page.Events.ResponseReceived, event.response));
|
client.on('Network.responseReceived', event => this.emit(Page.Events.ResponseReceived, event.response));
|
||||||
@ -391,6 +393,7 @@ class Page extends EventEmitter {
|
|||||||
* @return {!Promise<!Buffer>}
|
* @return {!Promise<!Buffer>}
|
||||||
*/
|
*/
|
||||||
async screenshot(options) {
|
async screenshot(options) {
|
||||||
|
options = options || {};
|
||||||
var screenshotType = null;
|
var screenshotType = null;
|
||||||
if (options.path) {
|
if (options.path) {
|
||||||
var mimeType = mime.lookup(options.path);
|
var mimeType = mime.lookup(options.path);
|
||||||
@ -423,7 +426,16 @@ class Page extends EventEmitter {
|
|||||||
console.assert(typeof options.clip.width === 'number', 'Expected options.clip.width to be a number but found ' + (typeof options.clip.width));
|
console.assert(typeof options.clip.width === 'number', 'Expected options.clip.width to be a number but found ' + (typeof options.clip.width));
|
||||||
console.assert(typeof options.clip.height === 'number', 'Expected options.clip.height to be a number but found ' + (typeof options.clip.height));
|
console.assert(typeof options.clip.height === 'number', 'Expected options.clip.height to be a number but found ' + (typeof options.clip.height));
|
||||||
}
|
}
|
||||||
|
this._screenshotTaskChain = this._screenshotTaskChain.then(this._screenshotTask.bind(this, screenshotType, options));
|
||||||
|
return this._screenshotTaskChain;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} screenshotType
|
||||||
|
* @param {!Object=} options
|
||||||
|
* @return {!Promise<!Buffer>}
|
||||||
|
*/
|
||||||
|
async _screenshotTask(screenshotType, options) {
|
||||||
if (options.clip) {
|
if (options.clip) {
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
this._client.send('Emulation.setVisibleSize', {
|
this._client.send('Emulation.setVisibleSize', {
|
||||||
|
@ -70,6 +70,23 @@ describe('GoldenTests', function() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
imageTest('screenshot-parallel-calls.png', async function() {
|
||||||
|
await page.setViewportSize({width: 500, height: 500});
|
||||||
|
await page.navigate(STATIC_PREFIX + '/grid.html');
|
||||||
|
var promises = [];
|
||||||
|
for (var i = 0; i < 3; ++i) {
|
||||||
|
promises.push(page.screenshot({
|
||||||
|
clip: {
|
||||||
|
x: 50 * i,
|
||||||
|
y: 0,
|
||||||
|
width: 50,
|
||||||
|
height: 50
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
return await promises[1];
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user