2013-03-13 08:51:30 +04:00
|
|
|
/* Any copyright is dedicated to the Public Domain.
|
|
|
|
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
|
|
|
|
2015-11-11 05:48:31 +03:00
|
|
|
/* global helpers, btoa, whenDelayedStartupFinished, OpenBrowserWindow */
|
|
|
|
|
2013-03-13 08:51:30 +04:00
|
|
|
// Test that screenshot command works properly
|
2015-09-21 20:07:31 +03:00
|
|
|
const TEST_URI = "http://example.com/browser/devtools/client/commandline/" +
|
2013-03-13 08:51:30 +04:00
|
|
|
"test/browser_cmd_screenshot.html";
|
|
|
|
|
2015-09-15 21:19:45 +03:00
|
|
|
var FileUtils = (Cu.import("resource://gre/modules/FileUtils.jsm", {})).FileUtils;
|
2013-03-13 08:51:30 +04:00
|
|
|
|
2013-09-03 15:20:27 +04:00
|
|
|
function test() {
|
|
|
|
return Task.spawn(spawnTest).then(finish, helpers.handleError);
|
|
|
|
}
|
|
|
|
|
2015-04-23 12:24:49 +03:00
|
|
|
function* spawnTest() {
|
2013-09-03 15:20:27 +04:00
|
|
|
waitForExplicitFinish();
|
|
|
|
|
|
|
|
info("RUN TEST: non-private window");
|
|
|
|
let normWin = yield addWindow({ private: false });
|
|
|
|
yield addTabWithToolbarRunTests(normWin);
|
|
|
|
normWin.close();
|
|
|
|
|
|
|
|
info("RUN TEST: private window");
|
|
|
|
let pbWin = yield addWindow({ private: true });
|
|
|
|
yield addTabWithToolbarRunTests(pbWin);
|
|
|
|
pbWin.close();
|
|
|
|
}
|
|
|
|
|
2015-05-25 15:42:51 +03:00
|
|
|
function* addTabWithToolbarRunTests(win) {
|
2013-09-03 15:20:27 +04:00
|
|
|
let options = yield helpers.openTab(TEST_URI, { chromeWindow: win });
|
2015-11-11 05:48:31 +03:00
|
|
|
let browser = options.browser;
|
2013-09-03 15:20:27 +04:00
|
|
|
yield helpers.openToolbar(options);
|
|
|
|
|
|
|
|
// Test input status
|
|
|
|
yield helpers.audit(options, [
|
|
|
|
{
|
2016-05-17 21:25:54 +03:00
|
|
|
setup: "screenshot",
|
2013-09-03 15:20:27 +04:00
|
|
|
check: {
|
2016-05-17 21:25:54 +03:00
|
|
|
input: "screenshot",
|
|
|
|
markup: "VVVVVVVVVV",
|
|
|
|
status: "VALID",
|
2013-09-03 15:20:27 +04:00
|
|
|
args: {
|
|
|
|
}
|
2013-03-13 08:51:30 +04:00
|
|
|
},
|
2013-09-03 15:20:27 +04:00
|
|
|
},
|
|
|
|
{
|
2016-05-17 21:25:54 +03:00
|
|
|
setup: "screenshot abc.png",
|
2013-09-03 15:20:27 +04:00
|
|
|
check: {
|
2016-05-17 21:25:54 +03:00
|
|
|
input: "screenshot abc.png",
|
|
|
|
markup: "VVVVVVVVVVVVVVVVVV",
|
|
|
|
status: "VALID",
|
2013-09-03 15:20:27 +04:00
|
|
|
args: {
|
|
|
|
filename: { value: "abc.png"},
|
|
|
|
}
|
2013-03-13 08:51:30 +04:00
|
|
|
},
|
2013-09-03 15:20:27 +04:00
|
|
|
},
|
|
|
|
{
|
2016-05-17 21:25:54 +03:00
|
|
|
setup: "screenshot --fullpage",
|
2013-09-03 15:20:27 +04:00
|
|
|
check: {
|
2016-05-17 21:25:54 +03:00
|
|
|
input: "screenshot --fullpage",
|
|
|
|
markup: "VVVVVVVVVVVVVVVVVVVVV",
|
|
|
|
status: "VALID",
|
2013-09-03 15:20:27 +04:00
|
|
|
args: {
|
|
|
|
fullpage: { value: true},
|
|
|
|
}
|
2013-03-13 08:51:30 +04:00
|
|
|
},
|
2013-09-03 15:20:27 +04:00
|
|
|
},
|
|
|
|
{
|
2016-05-17 21:25:54 +03:00
|
|
|
setup: "screenshot abc --delay 5",
|
2013-09-03 15:20:27 +04:00
|
|
|
check: {
|
2016-05-17 21:25:54 +03:00
|
|
|
input: "screenshot abc --delay 5",
|
|
|
|
markup: "VVVVVVVVVVVVVVVVVVVVVVVV",
|
|
|
|
status: "VALID",
|
2013-09-03 15:20:27 +04:00
|
|
|
args: {
|
|
|
|
filename: { value: "abc"},
|
|
|
|
delay: { value: 5 },
|
|
|
|
}
|
2013-03-13 08:51:30 +04:00
|
|
|
},
|
2013-09-03 15:20:27 +04:00
|
|
|
},
|
|
|
|
{
|
2016-05-17 21:25:54 +03:00
|
|
|
setup: "screenshot --selector img#testImage",
|
2013-09-03 15:20:27 +04:00
|
|
|
check: {
|
2016-05-17 21:25:54 +03:00
|
|
|
input: "screenshot --selector img#testImage",
|
|
|
|
markup: "VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV",
|
|
|
|
status: "VALID",
|
2013-03-13 08:51:30 +04:00
|
|
|
},
|
2013-09-03 15:20:27 +04:00
|
|
|
},
|
|
|
|
]);
|
|
|
|
|
|
|
|
// Test capture to file
|
|
|
|
let file = FileUtils.getFile("TmpD", [ "TestScreenshotFile.png" ]);
|
|
|
|
|
|
|
|
yield helpers.audit(options, [
|
|
|
|
{
|
2016-05-17 21:25:54 +03:00
|
|
|
setup: "screenshot " + file.path,
|
2013-09-03 15:20:27 +04:00
|
|
|
check: {
|
|
|
|
args: {
|
|
|
|
filename: { value: "" + file.path },
|
|
|
|
fullpage: { value: false },
|
|
|
|
clipboard: { value: false },
|
2013-03-13 08:51:30 +04:00
|
|
|
},
|
|
|
|
},
|
2013-09-03 15:20:27 +04:00
|
|
|
exec: {
|
|
|
|
output: new RegExp("^Saved to "),
|
|
|
|
},
|
2016-05-17 21:25:54 +03:00
|
|
|
post: function () {
|
2013-09-03 15:20:27 +04:00
|
|
|
// Bug 849168: screenshot command tests fail in try but not locally
|
|
|
|
// ok(file.exists(), "Screenshot file exists");
|
2013-03-13 08:51:30 +04:00
|
|
|
|
2013-09-03 15:20:27 +04:00
|
|
|
if (file.exists()) {
|
|
|
|
file.remove(false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
]);
|
|
|
|
|
|
|
|
// Test capture to clipboard
|
|
|
|
yield helpers.audit(options, [
|
|
|
|
{
|
2015-11-11 05:48:31 +03:00
|
|
|
setup: "screenshot --clipboard",
|
|
|
|
check: {
|
|
|
|
args: {
|
|
|
|
clipboard: { value: true },
|
|
|
|
},
|
|
|
|
},
|
|
|
|
exec: {
|
|
|
|
output: new RegExp("^Copied to clipboard.$"),
|
|
|
|
},
|
2016-05-17 21:25:54 +03:00
|
|
|
post: Task.async(function* () {
|
2015-11-11 05:48:31 +03:00
|
|
|
let imgSize = yield getImageSizeFromClipboard();
|
2016-05-17 21:25:54 +03:00
|
|
|
yield ContentTask.spawn(browser, imgSize, function* (imgSize) {
|
2016-03-04 16:32:27 +03:00
|
|
|
Assert.equal(imgSize.width, content.innerWidth, "Image width matches window size");
|
|
|
|
Assert.equal(imgSize.height, content.innerHeight, "Image height matches window size");
|
2015-11-11 05:48:31 +03:00
|
|
|
});
|
|
|
|
})
|
|
|
|
},
|
|
|
|
{
|
|
|
|
setup: "screenshot --fullpage --clipboard",
|
2013-09-03 15:20:27 +04:00
|
|
|
check: {
|
|
|
|
args: {
|
|
|
|
fullpage: { value: true },
|
|
|
|
clipboard: { value: true },
|
|
|
|
},
|
|
|
|
},
|
|
|
|
exec: {
|
|
|
|
output: new RegExp("^Copied to clipboard.$"),
|
|
|
|
},
|
2016-05-17 21:25:54 +03:00
|
|
|
post: Task.async(function* () {
|
2015-11-11 05:48:31 +03:00
|
|
|
let imgSize = yield getImageSizeFromClipboard();
|
2016-05-17 21:25:54 +03:00
|
|
|
yield ContentTask.spawn(browser, imgSize, function* (imgSize) {
|
2016-03-04 16:32:27 +03:00
|
|
|
Assert.equal(imgSize.width,
|
|
|
|
content.innerWidth + content.scrollMaxX - content.scrollMinX,
|
|
|
|
"Image width matches page size");
|
|
|
|
Assert.equal(imgSize.height,
|
|
|
|
content.innerHeight + content.scrollMaxY - content.scrollMinY,
|
|
|
|
"Image height matches page size");
|
2015-11-11 05:48:31 +03:00
|
|
|
});
|
|
|
|
})
|
|
|
|
},
|
|
|
|
{
|
|
|
|
setup: "screenshot --selector img#testImage --clipboard",
|
|
|
|
check: {
|
|
|
|
args: {
|
|
|
|
clipboard: { value: true },
|
|
|
|
},
|
|
|
|
},
|
|
|
|
exec: {
|
|
|
|
output: new RegExp("^Copied to clipboard.$"),
|
|
|
|
},
|
2016-05-17 21:25:54 +03:00
|
|
|
post: Task.async(function* () {
|
2015-11-11 05:48:31 +03:00
|
|
|
let imgSize = yield getImageSizeFromClipboard();
|
2016-05-17 21:25:54 +03:00
|
|
|
yield ContentTask.spawn(browser, imgSize, function* (imgSize) {
|
2015-11-11 05:48:31 +03:00
|
|
|
let img = content.document.querySelector("img#testImage");
|
2016-03-04 16:32:27 +03:00
|
|
|
Assert.equal(imgSize.width, img.clientWidth,
|
|
|
|
"Image width matches element size");
|
|
|
|
Assert.equal(imgSize.height, img.clientHeight,
|
|
|
|
"Image height matches element size");
|
2015-11-11 05:48:31 +03:00
|
|
|
});
|
|
|
|
})
|
|
|
|
},
|
|
|
|
]);
|
2013-03-13 08:51:30 +04:00
|
|
|
|
2015-11-11 05:48:31 +03:00
|
|
|
// Trigger scrollbars by forcing document to overflow
|
|
|
|
// This only affects results on OSes with scrollbars that reduce document size
|
|
|
|
// (non-floating scrollbars). With default OS settings, this means Windows
|
|
|
|
// and Linux are affected, but Mac is not. For Mac to exhibit this behavior,
|
|
|
|
// change System Preferences -> General -> Show scroll bars to Always.
|
2016-05-17 21:25:54 +03:00
|
|
|
yield ContentTask.spawn(browser, {}, function* () {
|
2015-11-11 05:48:31 +03:00
|
|
|
content.document.body.classList.add("overflow");
|
|
|
|
});
|
|
|
|
|
2016-05-17 21:25:54 +03:00
|
|
|
let scrollbarSize = yield ContentTask.spawn(browser, {}, function* () {
|
2015-11-11 05:48:31 +03:00
|
|
|
const winUtils = content.QueryInterface(Ci.nsIInterfaceRequestor)
|
|
|
|
.getInterface(Ci.nsIDOMWindowUtils);
|
|
|
|
let scrollbarHeight = {};
|
|
|
|
let scrollbarWidth = {};
|
|
|
|
winUtils.getScrollbarSize(true, scrollbarWidth, scrollbarHeight);
|
|
|
|
return {
|
|
|
|
width: scrollbarWidth.value,
|
|
|
|
height: scrollbarHeight.value,
|
|
|
|
};
|
|
|
|
});
|
|
|
|
|
|
|
|
info(`Scrollbar size: ${scrollbarSize.width}x${scrollbarSize.height}`);
|
|
|
|
|
|
|
|
// Test capture to clipboard in presence of scrollbars
|
|
|
|
yield helpers.audit(options, [
|
|
|
|
{
|
|
|
|
setup: "screenshot --clipboard",
|
|
|
|
check: {
|
|
|
|
args: {
|
|
|
|
clipboard: { value: true },
|
|
|
|
},
|
|
|
|
},
|
|
|
|
exec: {
|
|
|
|
output: new RegExp("^Copied to clipboard.$"),
|
|
|
|
},
|
2016-05-17 21:25:54 +03:00
|
|
|
post: Task.async(function* () {
|
2015-11-11 05:48:31 +03:00
|
|
|
let imgSize = yield getImageSizeFromClipboard();
|
2016-03-04 16:32:27 +03:00
|
|
|
imgSize.scrollbarWidth = scrollbarSize.width;
|
|
|
|
imgSize.scrollbarHeight = scrollbarSize.height;
|
2016-05-17 21:25:54 +03:00
|
|
|
yield ContentTask.spawn(browser, imgSize, function* (imgSize) {
|
2016-03-04 16:32:27 +03:00
|
|
|
Assert.equal(imgSize.width, content.innerWidth - imgSize.scrollbarWidth,
|
|
|
|
"Image width matches window size minus scrollbar size");
|
|
|
|
Assert.equal(imgSize.height, content.innerHeight - imgSize.scrollbarHeight,
|
|
|
|
"Image height matches window size minus scrollbar size");
|
2015-11-11 05:48:31 +03:00
|
|
|
});
|
|
|
|
})
|
|
|
|
},
|
|
|
|
{
|
|
|
|
setup: "screenshot --fullpage --clipboard",
|
|
|
|
check: {
|
|
|
|
args: {
|
|
|
|
fullpage: { value: true },
|
|
|
|
clipboard: { value: true },
|
|
|
|
},
|
|
|
|
},
|
|
|
|
exec: {
|
|
|
|
output: new RegExp("^Copied to clipboard.$"),
|
|
|
|
},
|
2016-05-17 21:25:54 +03:00
|
|
|
post: Task.async(function* () {
|
2015-11-11 05:48:31 +03:00
|
|
|
let imgSize = yield getImageSizeFromClipboard();
|
2016-03-04 16:32:27 +03:00
|
|
|
imgSize.scrollbarWidth = scrollbarSize.width;
|
|
|
|
imgSize.scrollbarHeight = scrollbarSize.height;
|
2016-05-17 21:25:54 +03:00
|
|
|
yield ContentTask.spawn(browser, imgSize, function* (imgSize) {
|
2016-03-04 16:32:27 +03:00
|
|
|
Assert.equal(imgSize.width,
|
|
|
|
(content.innerWidth + content.scrollMaxX - content.scrollMinX) - imgSize.scrollbarWidth,
|
|
|
|
"Image width matches page size minus scrollbar size");
|
|
|
|
Assert.equal(imgSize.height,
|
|
|
|
(content.innerHeight + content.scrollMaxY - content.scrollMinY) - imgSize.scrollbarHeight,
|
|
|
|
"Image height matches page size minus scrollbar size");
|
2015-11-11 05:48:31 +03:00
|
|
|
});
|
|
|
|
})
|
|
|
|
},
|
|
|
|
{
|
|
|
|
setup: "screenshot --selector img#testImage --clipboard",
|
|
|
|
check: {
|
|
|
|
args: {
|
|
|
|
clipboard: { value: true },
|
|
|
|
},
|
|
|
|
},
|
|
|
|
exec: {
|
|
|
|
output: new RegExp("^Copied to clipboard.$"),
|
|
|
|
},
|
2016-05-17 21:25:54 +03:00
|
|
|
post: Task.async(function* () {
|
2015-11-11 05:48:31 +03:00
|
|
|
let imgSize = yield getImageSizeFromClipboard();
|
2016-05-17 21:25:54 +03:00
|
|
|
yield ContentTask.spawn(browser, imgSize, function* (imgSize) {
|
2015-11-11 05:48:31 +03:00
|
|
|
let img = content.document.querySelector("img#testImage");
|
2016-03-04 16:32:27 +03:00
|
|
|
Assert.equal(imgSize.width, img.clientWidth,
|
|
|
|
"Image width matches element size");
|
|
|
|
Assert.equal(imgSize.height, img.clientHeight,
|
|
|
|
"Image height matches element size");
|
2015-11-11 05:48:31 +03:00
|
|
|
});
|
|
|
|
})
|
2013-09-03 15:20:27 +04:00
|
|
|
},
|
|
|
|
]);
|
2013-03-13 08:51:30 +04:00
|
|
|
|
2013-09-03 15:20:27 +04:00
|
|
|
yield helpers.closeToolbar(options);
|
|
|
|
yield helpers.closeTab(options);
|
2013-03-13 08:51:30 +04:00
|
|
|
}
|
|
|
|
|
2013-09-03 15:20:27 +04:00
|
|
|
function addWindow(windowOptions) {
|
2014-06-09 18:16:26 +04:00
|
|
|
return new Promise(resolve => {
|
|
|
|
let win = OpenBrowserWindow(windowOptions);
|
|
|
|
|
|
|
|
// This feels hacky, we should refactor it
|
|
|
|
whenDelayedStartupFinished(win, () => {
|
|
|
|
// Would like to get rid of this executeSoon, but without it the url
|
|
|
|
// (TEST_URI) provided in addTabWithToolbarRunTests hasn't loaded
|
|
|
|
executeSoon(() => {
|
|
|
|
resolve(win);
|
|
|
|
});
|
2013-03-13 08:51:30 +04:00
|
|
|
});
|
2013-12-12 00:36:24 +04:00
|
|
|
});
|
2013-03-13 08:51:30 +04:00
|
|
|
}
|
2015-11-11 05:48:31 +03:00
|
|
|
|
2016-05-17 21:25:54 +03:00
|
|
|
let getImageSizeFromClipboard = Task.async(function* () {
|
2015-11-11 05:48:31 +03:00
|
|
|
let clipid = Ci.nsIClipboard;
|
|
|
|
let clip = Cc["@mozilla.org/widget/clipboard;1"].getService(clipid);
|
|
|
|
let trans = Cc["@mozilla.org/widget/transferable;1"]
|
|
|
|
.createInstance(Ci.nsITransferable);
|
|
|
|
let flavor = "image/png";
|
|
|
|
trans.init(null);
|
|
|
|
trans.addDataFlavor(flavor);
|
|
|
|
|
|
|
|
clip.getData(trans, clipid.kGlobalClipboard);
|
|
|
|
let data = new Object();
|
|
|
|
let dataLength = new Object();
|
|
|
|
trans.getTransferData(flavor, data, dataLength);
|
|
|
|
|
|
|
|
ok(data.value, "screenshot exists");
|
|
|
|
ok(dataLength.value > 0, "screenshot has length");
|
|
|
|
|
|
|
|
let image = data.value;
|
|
|
|
let dataURI = `data:${flavor};base64,`;
|
|
|
|
|
|
|
|
// Due to the differences in how images could be stored in the clipboard the
|
|
|
|
// checks below are needed. The clipboard could already provide the image as
|
|
|
|
// byte streams, but also as pointer, or as image container. If it's not
|
|
|
|
// possible obtain a byte stream, the function returns `null`.
|
|
|
|
if (image instanceof Ci.nsISupportsInterfacePointer) {
|
|
|
|
image = image.data;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (image instanceof Ci.imgIContainer) {
|
|
|
|
image = Cc["@mozilla.org/image/tools;1"]
|
|
|
|
.getService(Ci.imgITools)
|
|
|
|
.encodeImage(image, flavor);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (image instanceof Ci.nsIInputStream) {
|
|
|
|
let binaryStream = Cc["@mozilla.org/binaryinputstream;1"]
|
|
|
|
.createInstance(Ci.nsIBinaryInputStream);
|
|
|
|
binaryStream.setInputStream(image);
|
|
|
|
let rawData = binaryStream.readBytes(binaryStream.available());
|
|
|
|
let charCodes = Array.from(rawData, c => c.charCodeAt(0) & 0xff);
|
|
|
|
let encodedData = String.fromCharCode(...charCodes);
|
|
|
|
encodedData = btoa(encodedData);
|
|
|
|
dataURI = dataURI + encodedData;
|
|
|
|
} else {
|
|
|
|
throw new Error("Unable to read image data");
|
|
|
|
}
|
|
|
|
|
|
|
|
let img = document.createElementNS("http://www.w3.org/1999/xhtml", "img");
|
|
|
|
|
|
|
|
let loaded = new Promise(resolve => {
|
|
|
|
img.addEventListener("load", function onLoad() {
|
|
|
|
img.removeEventListener("load", onLoad);
|
|
|
|
resolve();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
img.src = dataURI;
|
|
|
|
document.documentElement.appendChild(img);
|
|
|
|
yield loaded;
|
|
|
|
img.remove();
|
|
|
|
|
|
|
|
return {
|
|
|
|
width: img.width,
|
|
|
|
height: img.height,
|
|
|
|
};
|
|
|
|
});
|