Bug 1101628 - Refactor snapshotting code to allow reusing it across tests. r=botond

MozReview-Commit-ID: BRSUNn5gxSX
This commit is contained in:
Kartikaya Gupta 2016-06-01 15:48:05 -04:00
parent 7f2fcbb03b
commit e0de7153a9
3 changed files with 61 additions and 28 deletions

View File

@ -90,6 +90,20 @@ function coordinatesRelativeToScreen(aX, aY, aElement) {
};
}
// Get the bounding box of aElement, and return it in device pixels
// relative to the screen.
function rectRelativeToScreen(aElement) {
var targetWindow = aElement.ownerDocument.defaultView;
var scale = targetWindow.devicePixelRatio;
var rect = aElement.getBoundingClientRect();
return {
x: (targetWindow.mozInnerScreenX + rect.left) * scale,
y: (targetWindow.mozInnerScreenY + rect.top) * scale,
w: (rect.width * scale),
h: (rect.height * scale)
};
}
// Synthesizes a native mousewheel event and returns immediately. This does not
// guarantee anything; you probably want to use one of the other functions below
// which actually wait for results.

View File

@ -267,3 +267,48 @@ function runContinuation(testFunction) {
});
};
}
// Take a snapshot of the given rect, *including compositor transforms* (i.e.
// includes async scroll transforms applied by APZ). If you don't need the
// compositor transforms, you can probably get away with using
// SpecialPowers.snapshotWindowWithOptions or one of the friendlier wrappers.
// The rect provided is expected to be relative to the screen, for example as
// returned by rectRelativeToScreen in apz_test_native_event_utils.js.
// Example usage:
// var snapshot = getSnapshot(rectRelativeToScreen(myDiv));
// which will take a snapshot of the 'myDiv' element. Note that if part of the
// element is obscured by other things on top, the snapshot will include those
// things. If it is clipped by a scroll container, the snapshot will include
// that area anyway, so you will probably get parts of the scroll container in
// the snapshot. If the rect extends outside the browser window then the
// results are undefined.
// The snapshot is returned in the form of a data URL.
function getSnapshot(rect) {
function parentProcessSnapshot() {
addMessageListener('snapshot', function(rect) {
Components.utils.import('resource://gre/modules/Services.jsm');
var topWin = Services.wm.getMostRecentWindow('navigator:browser');
// reposition the rect relative to the top-level browser window
rect = JSON.parse(rect);
rect.x -= topWin.mozInnerScreenX;
rect.y -= topWin.mozInnerScreenY;
// take the snapshot
var canvas = topWin.document.createElementNS("http://www.w3.org/1999/xhtml", "canvas");
canvas.width = rect.w;
canvas.height = rect.h;
var ctx = canvas.getContext("2d");
ctx.drawWindow(topWin, rect.x, rect.y, rect.w, rect.h, 'rgb(255,255,255)', ctx.DRAWWINDOW_DRAW_VIEW | ctx.DRAWWINDOW_USE_WIDGET_LAYERS | ctx.DRAWWINDOW_DRAW_CARET);
return canvas.toDataURL();
});
}
if (typeof getSnapshot.chromeHelper == 'undefined') {
// This is the first time getSnapshot is being called; do initialization
getSnapshot.chromeHelper = SpecialPowers.loadChromeScript(parentProcessSnapshot);
SimpleTest.registerCleanupFunction(function() { getSnapshot.chromeHelper.destroy() });
}
return getSnapshot.chromeHelper.sendSyncMessage('snapshot', JSON.stringify(rect)).toString();
}

View File

@ -27,26 +27,6 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1203140
const kResponseTimeoutMs = 2 * 60 * 1000; // 2 minutes
function parentProcessSnapshot() {
addMessageListener('snapshot', function(rect) {
Components.utils.import('resource://gre/modules/Services.jsm');
var topWin = Services.wm.getMostRecentWindow('navigator:browser');
// reposition the rect relative to the top-level browser window
rect = JSON.parse(rect);
rect.x -= topWin.mozInnerScreenX;
rect.y -= topWin.mozInnerScreenY;
// take the snapshot
var canvas = topWin.document.createElementNS("http://www.w3.org/1999/xhtml", "canvas");
canvas.width = rect.w;
canvas.height = rect.h;
var ctx = canvas.getContext("2d");
ctx.drawWindow(topWin, rect.x, rect.y, rect.w, rect.h, 'rgb(255,255,255)', ctx.DRAWWINDOW_DRAW_VIEW | ctx.DRAWWINDOW_USE_WIDGET_LAYERS | ctx.DRAWWINDOW_DRAW_CARET);
return canvas.toDataURL();
});
}
function takeSnapshots(e) {
// Grab some snapshots, and make sure some of them are different (i.e. check
// the page is scrolling in the compositor, concurrently with this wheel
@ -58,18 +38,12 @@ function takeSnapshots(e) {
var lastSnapshot = null;
var success = false;
var chromeHelper = SpecialPowers.loadChromeScript(parentProcessSnapshot);
SimpleTest.registerCleanupFunction(function() { chromeHelper.destroy() });
// Get the position of the 'content' div relative to the screen
var contentDiv = document.getElementById('content');
var rect = coordinatesRelativeToWindow(0, 0, contentDiv);
rect.w = contentDiv.getBoundingClientRect().width * window.devicePixelRatio;
rect.h = contentDiv.getBoundingClientRect().height * window.devicePixelRatio;
var rect = rectRelativeToScreen(document.getElementById('content'));
for (var i = 0; i < 10; i++) {
SpecialPowers.DOMWindowUtils.advanceTimeAndRefresh(16);
var snapshot = chromeHelper.sendSyncMessage('snapshot', JSON.stringify(rect)).toString();
var snapshot = getSnapshot(rect);
//dump("Took snapshot " + snapshot + "\n"); // this might help with debugging
if (lastSnapshot && lastSnapshot != snapshot) {