Added automated testing with selenium

This commit is contained in:
MoyuScript 2012-12-22 16:28:34 +02:00
parent 4ab5a5eb00
commit b5691592ef
6 changed files with 217 additions and 134 deletions

View File

@ -1,4 +1,4 @@
_html2canvas.Parse = function ( images, options ) { _html2canvas.Parse = function (images, options) {
window.scroll(0,0); window.scroll(0,0);
var support = { var support = {
@ -96,16 +96,16 @@ _html2canvas.Parse = function ( images, options ) {
} }
var getCSS = _html2canvas.Util.getCSS; var getCSS = _html2canvas.Util.getCSS;
function getCSSInt(element, attribute) { function getCSSInt(element, attribute) {
var val = parseInt(getCSS(element, attribute), 10); var val = parseInt(getCSS(element, attribute), 10);
return (isNaN(val)) ? 0 : val; // borders in old IE are throwing 'medium' for demo.html return (isNaN(val)) ? 0 : val; // borders in old IE are throwing 'medium' for demo.html
} }
// Drawing a rectangle
function renderRect (ctx, x, y, w, h, bgcolor) { function renderRect (ctx, x, y, w, h, bgcolor) {
if (bgcolor !== "transparent"){ if (bgcolor !== "transparent"){
ctx.setVariable("fillStyle", bgcolor); ctx.setVariable("fillStyle", bgcolor);
ctx.fillRect (x, y, w, h); ctx.fillRect(x, y, w, h);
numDraws+=1; numDraws+=1;
} }
} }
@ -144,6 +144,7 @@ _html2canvas.Parse = function ( images, options ) {
var container = doc.createElement('div'), var container = doc.createElement('div'),
img = doc.createElement('img'), img = doc.createElement('img'),
span = doc.createElement('span'), span = doc.createElement('span'),
sampleText = 'Hidden Text',
baseline, baseline,
middle, middle,
metricsObj; metricsObj;
@ -170,13 +171,13 @@ _html2canvas.Parse = function ( images, options ) {
span.style.margin = 0; span.style.margin = 0;
span.style.padding = 0; span.style.padding = 0;
span.appendChild(doc.createTextNode('Hidden Text')); span.appendChild(doc.createTextNode(sampleText));
container.appendChild(span); container.appendChild(span);
container.appendChild(img); container.appendChild(img);
baseline = (img.offsetTop - span.offsetTop) + 1; baseline = (img.offsetTop - span.offsetTop) + 1;
container.removeChild(span); container.removeChild(span);
container.appendChild(doc.createTextNode('Hidden Text')); container.appendChild(doc.createTextNode(sampleText));
container.style.lineHeight = "normal"; container.style.lineHeight = "normal";
img.style.verticalAlign = "super"; img.style.verticalAlign = "super";
@ -222,6 +223,7 @@ _html2canvas.Parse = function ( images, options ) {
ctx.setVariable("fillStyle", color); ctx.setVariable("fillStyle", color);
ctx.setVariable("font", [font_style, font_variant, bold, size, family].join(" ")); ctx.setVariable("font", [font_style, font_variant, bold, size, family].join(" "));
ctx.setVariable("textAlign", (align) ? "right" : "left"); ctx.setVariable("textAlign", (align) ? "right" : "left");
if (text_decoration !== "none"){ if (text_decoration !== "none"){
return fontMetrics(family, size); return fontMetrics(family, size);
} }
@ -327,8 +329,9 @@ _html2canvas.Parse = function ( images, options ) {
} }
if (textValue !== null) {
drawText(textValue, bounds.left, bounds.bottom, ctx); drawText(textValue, bounds.left, bounds.bottom, ctx);
}
renderTextDecoration(text_decoration, bounds, metrics, color); renderTextDecoration(text_decoration, bounds, metrics, color);
textOffset += renderList[c].length; textOffset += renderList[c].length;
@ -341,21 +344,21 @@ _html2canvas.Parse = function ( images, options ) {
function listPosition (element, val) { function listPosition (element, val) {
var boundElement = doc.createElement( "boundelement" ), var boundElement = doc.createElement( "boundelement" ),
type, originalType,
bounds; bounds;
boundElement.style.display = "inline"; boundElement.style.display = "inline";
type = element.style.listStyleType; originalType = element.style.listStyleType;
element.style.listStyleType = "none"; element.style.listStyleType = "none";
boundElement.appendChild( doc.createTextNode( val ) ); boundElement.appendChild(doc.createTextNode(val));
element.insertBefore(boundElement, element.firstChild); element.insertBefore(boundElement, element.firstChild);
bounds = _html2canvas.Util.Bounds( boundElement ); bounds = _html2canvas.Util.Bounds(boundElement);
element.removeChild( boundElement ); element.removeChild(boundElement);
element.style.listStyleType = type; element.style.listStyleType = originalType;
return bounds; return bounds;
} }
@ -406,9 +409,7 @@ _html2canvas.Parse = function ( images, options ) {
} }
function renderListItem(element, stack, elBounds) { function renderListItem(element, stack, elBounds) {
var position = getCSS(element, "listStylePosition"), var x,
x,
y,
text, text,
type = getCSS(element, "listStyleType"), type = getCSS(element, "listStyleType"),
listBounds; listBounds;
@ -418,16 +419,14 @@ _html2canvas.Parse = function ( images, options ) {
listBounds = listPosition(element, text); listBounds = listPosition(element, text);
setTextVariables(ctx, element, "none", getCSS(element, "color")); setTextVariables(ctx, element, "none", getCSS(element, "color"));
if (position === "inside") { if (getCSS(element, "listStylePosition") === "inside") {
ctx.setVariable("textAlign", "left"); ctx.setVariable("textAlign", "left");
x = elBounds.left; x = elBounds.left;
} else { } else {
return; return;
} }
y = listBounds.bottom; drawText(text, x, listBounds.bottom, ctx);
drawText(text, x, y, ctx);
} }
} }
@ -731,15 +730,13 @@ _html2canvas.Parse = function ( images, options ) {
height, height,
add; add;
// if (typeof background_image !== "undefined" && /^(1|none)$/.test(background_image) === false && /^(-webkit|-moz|linear-gradient|-o-)/.test(background_image)===false){
if ( !/data:image\/.*;base64,/i.test(background_image) && !/^(-webkit|-moz|linear-gradient|-o-)/.test(background_image) ) { if ( !/data:image\/.*;base64,/i.test(background_image) && !/^(-webkit|-moz|linear-gradient|-o-)/.test(background_image) ) {
background_image = background_image.split(",")[0]; background_image = background_image.split(",")[0];
} }
if ( typeof background_image !== "undefined" && /^(1|none)$/.test( background_image ) === false ) { if ( typeof background_image !== "undefined" && /^(1|none)$/.test(background_image) === false ) {
background_image = _html2canvas.Util.backgroundImage( background_image ); background_image = _html2canvas.Util.backgroundImage(background_image);
image = loadImage( background_image ); image = loadImage(background_image);
bgp = _html2canvas.Util.BackgroundPosition(el, bounds, image); bgp = _html2canvas.Util.BackgroundPosition(el, bounds, image);
@ -748,11 +745,11 @@ _html2canvas.Parse = function ( images, options ) {
if ( image ){ if ( image ){
switch ( background_repeat ) { switch ( background_repeat ) {
case "repeat-x": case "repeat-x":
renderBackgroundRepeatX( ctx, image, bgp, bounds.left, bounds.top, bounds.width, bounds.height ); renderBackgroundRepeatX(ctx, image, bgp, bounds.left, bounds.top, bounds.width, bounds.height);
break; break;
case "repeat-y": case "repeat-y":
renderBackgroundRepeatY( ctx, image, bgp, bounds.left, bounds.top, bounds.width, bounds.height ); renderBackgroundRepeatY(ctx, image, bgp, bounds.left, bounds.top, bounds.width, bounds.height);
break; break;
case "no-repeat": case "no-repeat":
@ -890,18 +887,16 @@ _html2canvas.Parse = function ( images, options ) {
ctx.setVariable("globalAlpha", stack.opacity); ctx.setVariable("globalAlpha", stack.opacity);
// draw element borders
borders = renderBorders(el, ctx, bounds, false); borders = renderBorders(el, ctx, bounds, false);
stack.borders = borders; stack.borders = borders;
// let's modify clip area for child elements, so borders dont get overwritten
if (ignoreElementsRegExp.test(el.nodeName) && options.iframeDefault !== "transparent"){ if (ignoreElementsRegExp.test(el.nodeName) && options.iframeDefault !== "transparent"){
bgcolor = (options.iframeDefault === "default") ? "#efefef" : options.iframeDefault; bgcolor = (options.iframeDefault === "default") ? "#efefef" : options.iframeDefault;
} }
// draw base element bgcolor
bgbounds = { bgbounds = {
left: x + borders[3].width, left: x + borders[3].width,

View File

@ -20,19 +20,23 @@
if (options && options.profile && window.console && window.console.profileEnd) { if (options && options.profile && window.console && window.console.profileEnd) {
console.profileEnd(); console.profileEnd();
} }
$canvas.css({ $canvas.addClass("html2canvas")
.css({
position: 'absolute', position: 'absolute',
left: 0, left: 0,
top: 0 top: 0
}).appendTo(document.body); }).appendTo(document.body);
$canvas.siblings().toggle();
if (window.location.search !== "?selenium") {
$canvas.siblings().toggle();
$(window).click(function(){ $(window).click(function(){
$canvas.toggle().siblings().toggle(); $canvas.toggle().siblings().toggle();
throwMessage("Canvas Render " + ($canvas.is(':visible') ? "visible" : "hidden")); throwMessage("Canvas Render " + ($canvas.is(':visible') ? "visible" : "hidden"));
}); });
throwMessage('Screenshot created in '+ ((finishTime.getTime()-timer)) + " ms<br />",4000); throwMessage('Screenshot created in '+ ((finishTime.getTime()-timer)) + " ms<br />",4000);
} else {
$canvas.css('display', 'none');
}
// test if canvas is read-able // test if canvas is read-able
try { try {
$canvas[0].toDataURL(); $canvas[0].toDataURL();

View File

@ -94,7 +94,7 @@ _html2canvas.Renderer.Canvas = function( options ) {
canvas.height = canvas.style.height = (!usingFlashcanvas) ? options.height || zStack.ctx.height : Math.min(flashMaxSize, (options.height || zStack.ctx.height) ); canvas.height = canvas.style.height = (!usingFlashcanvas) ? options.height || zStack.ctx.height : Math.min(flashMaxSize, (options.height || zStack.ctx.height) );
fstyle = ctx.fillStyle; fstyle = ctx.fillStyle;
ctx.fillStyle = zStack.backgroundColor; ctx.fillStyle = (zStack.backgroundColor === "transparent") ? "#fff" : zStack.backgroundColor;
ctx.fillRect(0, 0, canvas.width, canvas.height); ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = fstyle; ctx.fillStyle = fstyle;

View File

@ -1,8 +1,3 @@
<!--
* @author Niklas von Hertzen <niklas at hertzen.com>
* @created 15.7.2011
* @website http://hertzen.com
-->
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>

View File

@ -1,8 +1,3 @@
<!--
* @author Niklas von Hertzen <niklas at hertzen.com>
* @created 15.7.2011
* @website http://hertzen.com
-->
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>

94
tests/selenium.js Normal file
View File

@ -0,0 +1,94 @@
var webdriver = require("webdriver.js").webdriver,
http = require("http"),
url = require("url"),
path = require("path"),
base64_arraybuffer = require('base64-arraybuffer'),
PNG = require('png-js'),
fs = require("fs"),
port = 5555;
var server = http.createServer(function(request, response) {
var uri = url.parse(request.url).pathname,
filename = path.join(process.cwd(), "../" + uri);
fs.exists(filename, function(exists) {
if(!exists) {
response.writeHead(404, {
"Content-Type": "text/plain"
});
response.write("404 Not Found\n");
response.end();
return;
}
if (fs.statSync(filename).isDirectory()) filename += '/index.html';
fs.readFile(filename, "binary", function(err, file) {
if(err) {
response.writeHead(500, {
"Content-Type": "text/plain"
});
response.write(err + "\n");
response.end();
return;
}
response.writeHead(200);
response.write(file, "binary");
response.end();
});
});
}).listen(port);
function getPixelArray(base64, func) {
var arraybuffer = base64_arraybuffer.decode(base64);
(new PNG(arraybuffer)).decode(func);
}
var browser = new webdriver({
logging:false
});
function testPage(url, done) {
browser.url("http://localhost:" + port + "/tests/" + url + "?selenium")
.$(".html2canvas", 5000, function(){
this.execute(function(){
var canvas = $('.html2canvas')[0];
return canvas.toDataURL("image/png").substring(22);
},[], function(dataurl) {
getPixelArray(dataurl, function(h2cPixels) {
browser.screenshot(function(base64){
getPixelArray(base64, function(screenPixels) {
var len = h2cPixels.length, index = 0, diff = 0;
for (; index < len; index++) {
if (screenPixels[index] - h2cPixels[index] !== 0) {
diff++;
}
}
done(100 - (Math.round((diff/h2cPixels.length) * 10000) / 100));
});
})
});
});
});
}
(function(pages) {
(function processPage(page) {
testPage(page, function(result) {
if (pages.length > 0) {
processPage(pages.shift());
} else {
browser.close(function(){
server.close();
});
}
console.log(page, result);
});
})(pages.shift());
})(["overflow.html", "forms.html", "lists.html"]);