mirror of
https://github.com/niklasvh/html2canvas.git
synced 2023-08-10 21:13:10 +03:00
Typescript conversion (#1828)
* initial typescript conversion * test: update overflow+transform ref test * fix: correctly render pseudo element content * fix: testrunner build * fix: karma test urls * test: update underline tests with <u> elements * test: update to es6-promise polyfill * test: remove watch from server * test: remove flow * format: update prettier for typescript * test: update eslint to use typescript parser * test: update linear gradient reftest * test: update test runner * test: update testrunner promise polyfill * fix: handle display: -webkit-flex correctly (fix #1817) * fix: correctly render gradients with clip & repeat (fix #1773) * fix: webkit-gradient function support * fix: implement radial gradients * fix: text-decoration rendering * fix: missing scroll positions for elements * ci: fix ios 11 tests * fix: ie logging * ci: improve device availability logging * fix: lint errors * ci: update to ios 12 * fix: check for console availability * ci: fix build dependency * test: update text reftests * fix: window reference for unit tests * feat: add hsl/hsla color support * fix: render options * fix: CSSKeyframesRule cssText Permission Denied on Internet Explorer 11 (#1830) * fix: option lint * fix: list type rendering * test: fix platform import * fix: ie css parsing for numbers * ci: add minified build * fix: form element rendering * fix: iframe rendering * fix: re-introduce experimental foreignobject renderer * fix: text-shadow rendering * feat: improve logging * fix: unit test logging * fix: cleanup resources * test: update overflow scrolling to work with ie * build: update build to include typings * fix: do not parse select element children * test: fix onclone test to work with older IEs * test: reduce reftest canvas sizes * test: remove dynamic setUp from list tests * test: update linear-gradient tests * build: remove old source files * build: update docs dependencies * build: fix typescript definition path * ci: include test.js on docs website
This commit is contained in:
@ -1,18 +0,0 @@
|
||||
{
|
||||
"curly": true,
|
||||
"eqeqeq": true,
|
||||
"immed": true,
|
||||
"latedef": false,
|
||||
"newcap": true,
|
||||
"noarg": true,
|
||||
"sub": true,
|
||||
"undef": true,
|
||||
"boss": true,
|
||||
"eqnull": true,
|
||||
"browser": true,
|
||||
"globals": {
|
||||
"jQuery": true
|
||||
},
|
||||
"predef": ["deepEqual", "module", "test", "$", "QUnit", "NodeParser", "NodeContainer", "StackingContext", "TextContainer", "ImageLoader", "CanvasRenderer", "Renderer", "Support", "bind", "Promise",
|
||||
"ImageContainer", "ProxyImageContainer", "DummyImageContainer", "Font", "FontMetrics", "GradientContainer", "LinearGradientContainer", "WebkitGradientContainer", "log", "smallImage", "parseBackgrounds"]
|
||||
}
|
@ -1,136 +0,0 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Mocha Tests</title>
|
||||
<link rel="stylesheet" href="lib/mocha.css" />
|
||||
<script src="../../node_modules/bluebird/js/browser/bluebird.js"></script>
|
||||
<script src="../../dist/html2canvas.js"></script>
|
||||
<script src="../assets/jquery-1.6.2.js"></script>
|
||||
<script src="lib/expect.js"></script>
|
||||
<script src="lib/mocha.js"></script>
|
||||
<style>
|
||||
#block {
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
}
|
||||
#green-block {
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
background: green;
|
||||
}
|
||||
#background-block {
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNgaGD4DwAChAGAJVtEDQAAAABJRU5ErkJggg==) red;
|
||||
}
|
||||
#gradient-block {
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
background-image: -webkit-linear-gradient(top, #008000, #008000);
|
||||
background-image: -moz-linear-gradient(to bottom, #008000, #008000);
|
||||
background-image: linear-gradient(to bottom, #008000, #008000);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="mocha"></div>
|
||||
<script>mocha.setup('bdd')</script>
|
||||
<div id="block"></div>
|
||||
<div id="green-block"></div>
|
||||
<div id="background-block"></div>
|
||||
<div id="gradient-block"></div>
|
||||
<script>
|
||||
describe("options.background", function() {
|
||||
it("with hexcolor", function(done) {
|
||||
html2canvas(document.querySelector("#block"), {background: '#008000'}).then(function(canvas) {
|
||||
expect(canvas.width).to.equal(200);
|
||||
expect(canvas.height).to.equal(200);
|
||||
validCanvasPixels(canvas);
|
||||
done();
|
||||
}).catch(function(error) {
|
||||
done(error);
|
||||
});
|
||||
});
|
||||
|
||||
it("with named color", function(done) {
|
||||
html2canvas(document.querySelector("#block"), {background: 'green'}).then(function(canvas) {
|
||||
expect(canvas.width).to.equal(200);
|
||||
expect(canvas.height).to.equal(200);
|
||||
validCanvasPixels(canvas);
|
||||
done();
|
||||
}).catch(function(error) {
|
||||
done(error);
|
||||
});
|
||||
});
|
||||
|
||||
it("with element background", function(done) {
|
||||
html2canvas(document.querySelector("#green-block"), {background: 'red'}).then(function(canvas) {
|
||||
expect(canvas.width).to.equal(200);
|
||||
expect(canvas.height).to.equal(200);
|
||||
validCanvasPixels(canvas);
|
||||
done();
|
||||
}).catch(function(error) {
|
||||
done(error);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('element background', function() {
|
||||
it('with background-color', function(done) {
|
||||
html2canvas(document.querySelector("#green-block")).then(function(canvas) {
|
||||
expect(canvas.width).to.equal(200);
|
||||
expect(canvas.height).to.equal(200);
|
||||
validCanvasPixels(canvas);
|
||||
done();
|
||||
}).catch(function(error) {
|
||||
done(error);
|
||||
});
|
||||
});
|
||||
|
||||
it('with background-image', function(done) {
|
||||
html2canvas(document.querySelector("#background-block")).then(function(canvas) {
|
||||
expect(canvas.width).to.equal(200);
|
||||
expect(canvas.height).to.equal(200);
|
||||
validCanvasPixels(canvas);
|
||||
done();
|
||||
}).catch(function(error) {
|
||||
done(error);
|
||||
});
|
||||
});
|
||||
|
||||
it('with gradient background-image', function(done) {
|
||||
html2canvas(document.querySelector("#gradient-block")).then(function(canvas) {
|
||||
expect(canvas.width).to.equal(200);
|
||||
expect(canvas.height).to.equal(200);
|
||||
validCanvasPixels(canvas);
|
||||
done();
|
||||
}).catch(function(error) {
|
||||
done(error);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function validCanvasPixels(canvas) {
|
||||
var ctx = canvas.getContext("2d");
|
||||
var data = ctx.getImageData(0, 0, canvas.width, canvas.height).data;
|
||||
for (var i = 0, len = data.length; i < len; i+=4) {
|
||||
if (data[i] !== 0 || data[i+1] !== 128 || data[i+2] !== 0 || data[i+3] !== 255) {
|
||||
expect().fail("Invalid canvas data");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mocha.checkLeaks();
|
||||
mocha.globals(['jQuery']);
|
||||
if (window.mochaPhantomJS) {
|
||||
mochaPhantomJS.run();
|
||||
}
|
||||
else {
|
||||
mocha.run();
|
||||
}
|
||||
mocha.suite.afterAll(function() {
|
||||
document.body.setAttribute('data-complete', 'true');
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -1 +0,0 @@
|
||||
document.querySelector('#block').className += 'class';
|
@ -1,145 +0,0 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Mocha Tests</title>
|
||||
<link rel="stylesheet" href="lib/mocha.css" />
|
||||
<script src="../../node_modules/bluebird/js/browser/bluebird.js"></script>
|
||||
<script src="../../dist/html2canvas.js"></script>
|
||||
<script src="../assets/jquery-1.6.2.js"></script>
|
||||
<script src="lib/expect.js"></script>
|
||||
<script src="lib/mocha.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="mocha"></div>
|
||||
<script>mocha.setup('bdd')</script>
|
||||
<div style="background: green; width: 40px; height:40px;" id="block"></div>
|
||||
<div style="visibility: hidden">
|
||||
<iframe src="iframe1.htm" style="height: 350px; width: 450px; border: 0;" scrolling="no" id="frame1"></iframe>
|
||||
<iframe src="iframe2.htm" style="height: 350px; width: 450px; border: 0;" scrolling="yes" id="frame2"></iframe>
|
||||
</div>
|
||||
<script>
|
||||
describe("Cropping", function() {
|
||||
it("window view with body", function(done) {
|
||||
html2canvas(document.body, {type: 'view'}).then(function(canvas) {
|
||||
expect(canvas.width).to.equal(window.innerWidth);
|
||||
expect(canvas.height).to.equal(window.innerHeight);
|
||||
done();
|
||||
}).catch(function(error) {
|
||||
done(error);
|
||||
});
|
||||
});
|
||||
|
||||
it("window view with documentElement", function(done) {
|
||||
html2canvas(document.documentElement, {type: 'view'}).then(function(canvas) {
|
||||
expect(canvas.width).to.equal(window.innerWidth);
|
||||
expect(canvas.height).to.equal(window.innerHeight);
|
||||
done();
|
||||
}).catch(function(error) {
|
||||
done(error);
|
||||
});
|
||||
});
|
||||
|
||||
it("iframe with body", function(done) {
|
||||
html2canvas(document.querySelector("#frame1").contentWindow.document.body, {type: 'view'}).then(function(canvas) {
|
||||
expect(canvas.width).to.equal(450);
|
||||
expect(canvas.height).to.equal(350);
|
||||
validCanvasPixels(canvas);
|
||||
done();
|
||||
}).catch(function(error) {
|
||||
done(error);
|
||||
});
|
||||
});
|
||||
|
||||
it("iframe with document element", function(done) {
|
||||
html2canvas(document.querySelector("#frame1").contentWindow.document.documentElement, {type: 'view'}).then(function(canvas) {
|
||||
expect(canvas.width).to.equal(450);
|
||||
expect(canvas.height).to.equal(350);
|
||||
validCanvasPixels(canvas);
|
||||
done();
|
||||
}).catch(function(error) {
|
||||
done(error);
|
||||
});
|
||||
});
|
||||
|
||||
it("with node", function(done) {
|
||||
html2canvas(document.querySelector("#block")).then(function(canvas) {
|
||||
expect(canvas.width).to.equal(40);
|
||||
expect(canvas.height).to.equal(40);
|
||||
validCanvasPixels(canvas);
|
||||
done();
|
||||
}).catch(function(error) {
|
||||
done(error);
|
||||
});
|
||||
});
|
||||
|
||||
it("with node and size", function(done) {
|
||||
html2canvas(document.querySelector("#block"), {width: 20, height: 20}).then(function(canvas) {
|
||||
expect(canvas.width).to.equal(20);
|
||||
expect(canvas.height).to.equal(20);
|
||||
validCanvasPixels(canvas);
|
||||
done();
|
||||
}).catch(function(error) {
|
||||
done(error);
|
||||
});
|
||||
});
|
||||
|
||||
document.querySelector("#frame2").addEventListener("load", function() {
|
||||
|
||||
document.querySelector("#frame2").contentWindow.scrollTo(0, 350);
|
||||
describe("with scrolled content", function() {
|
||||
it("iframe with body", function(done) {
|
||||
html2canvas(document.querySelector("#frame2").contentWindow.document.body, {type: 'view'}).then(function(canvas) {
|
||||
// phantomjs issue https://github.com/ariya/phantomjs/issues/10581
|
||||
if (canvas.height !== 1200) {
|
||||
expect(canvas.width).to.equal(450);
|
||||
expect(canvas.height).to.equal(350);
|
||||
validCanvasPixels(canvas);
|
||||
}
|
||||
done();
|
||||
}).catch(function(error) {
|
||||
done(error);
|
||||
});
|
||||
});
|
||||
|
||||
it("iframe with document element", function(done) {
|
||||
html2canvas(document.querySelector("#frame2").contentWindow.document.documentElement, {type: 'view'}).then(function(canvas) {
|
||||
// phantomjs issue https://github.com/ariya/phantomjs/issues/10581
|
||||
if (canvas.height !== 1200) {
|
||||
expect(canvas.width).to.equal(450);
|
||||
expect(canvas.height).to.equal(350);
|
||||
validCanvasPixels(canvas);
|
||||
}
|
||||
done();
|
||||
}).catch(function(error) {
|
||||
done(error);
|
||||
});
|
||||
});
|
||||
});
|
||||
}, false);
|
||||
});
|
||||
|
||||
|
||||
function validCanvasPixels(canvas) {
|
||||
var ctx = canvas.getContext("2d");
|
||||
var data = ctx.getImageData(0, 0, canvas.width, canvas.height).data;
|
||||
for (var i = 0, len = data.length; i < len; i+=4) {
|
||||
if (data[i] !== 0 || data[i+1] !== 128 || data[i+2] !== 0 || data[i+3] !== 255) {
|
||||
expect().fail("Invalid canvas data");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mocha.checkLeaks();
|
||||
mocha.globals(['jQuery']);
|
||||
if (window.mochaPhantomJS) {
|
||||
mochaPhantomJS.run();
|
||||
}
|
||||
else {
|
||||
mocha.run();
|
||||
}
|
||||
mocha.suite.afterAll(function() {
|
||||
document.body.setAttribute('data-complete', 'true');
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -1,241 +0,0 @@
|
||||
var NodeContainer = html2canvas.NodeContainer;
|
||||
|
||||
describe('Borders', function() {
|
||||
$('#borders div').each(function(i, node) {
|
||||
it($(this).attr('style'), function() {
|
||||
[
|
||||
'borderTopWidth',
|
||||
'borderRightWidth',
|
||||
'borderBottomWidth',
|
||||
'borderLeftWidth'
|
||||
].forEach(function(prop) {
|
||||
var result = $(node).css(prop);
|
||||
// older IE's don't necessarily return px even with jQuery
|
||||
if (result === 'thin') {
|
||||
result = '1px';
|
||||
} else if (result === 'medium') {
|
||||
result = '3px';
|
||||
} else if (result === 'thick') {
|
||||
result = '5px';
|
||||
}
|
||||
var container = new NodeContainer(node, null);
|
||||
expect(container.css(prop)).to.be(result);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Padding', function() {
|
||||
$('#padding div').each(function(i, node) {
|
||||
it($(this).attr('style'), function() {
|
||||
['paddingTop', 'paddingRight', 'paddingBottom', 'paddingLeft'].forEach(function(prop) {
|
||||
var container = new NodeContainer(node, null);
|
||||
var result = container.css(prop);
|
||||
expect(result).to.contain('px');
|
||||
expect(result, $(node).css(prop));
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Background-position', function() {
|
||||
$('#backgroundPosition div').each(function(i, node) {
|
||||
it($(this).attr('style'), function() {
|
||||
var prop = 'backgroundPosition';
|
||||
var img = new Image();
|
||||
img.width = 50;
|
||||
img.height = 50;
|
||||
|
||||
var container = new NodeContainer(node, null);
|
||||
var item = container.css(prop),
|
||||
backgroundPosition = container.parseBackgroundPosition(
|
||||
html2canvas.utils.getBounds(node),
|
||||
img
|
||||
),
|
||||
split = window.getComputedStyle
|
||||
? $(node).css(prop).split(' ')
|
||||
: [$(node).css(prop + 'X'), $(node).css(prop + 'Y')];
|
||||
|
||||
var testEl = $('<div />').css({
|
||||
position: 'absolute',
|
||||
left: split[0],
|
||||
top: split[1]
|
||||
});
|
||||
|
||||
testEl.appendTo(node);
|
||||
|
||||
expect(backgroundPosition.left).to.equal(Math.floor(parseFloat(testEl.css('left'))));
|
||||
expect(backgroundPosition.top).to.equal(Math.floor(parseFloat(testEl.css('top'))));
|
||||
|
||||
testEl.remove();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Text-shadow', function() {
|
||||
$('#textShadows div').each(function(i, node) {
|
||||
var index = i + 1;
|
||||
var container = new NodeContainer(node, null);
|
||||
var shadows = container.parseTextShadows();
|
||||
it(node.style.textShadow, function() {
|
||||
if (i === 0) {
|
||||
expect(shadows.length).to.equal(0);
|
||||
} else {
|
||||
expect(shadows.length).to.equal(i >= 6 ? 2 : 1);
|
||||
expect(shadows[0].offsetX).to.equal(i);
|
||||
expect(shadows[0].offsetY).to.equal(i);
|
||||
if (i < 2) {
|
||||
expect(shadows[0].color.toString()).to.equal('rgba(0,0,0,0)');
|
||||
} else if (i % 2 === 0) {
|
||||
expect(shadows[0].color.toString()).to.equal('rgb(2,2,2)');
|
||||
} else {
|
||||
var opacity = '0.2';
|
||||
expect(shadows[0].color.toString()).to.match(/rgba\(2,2,2,(0.2|0\.199219)\)/);
|
||||
}
|
||||
|
||||
// only testing blur once
|
||||
if (i === 1) {
|
||||
expect(shadows[0].blur).to.equal('1');
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Background-image', function() {
|
||||
test_parse_background_image(
|
||||
'url("te)st")',
|
||||
{
|
||||
prefix: '',
|
||||
method: 'url',
|
||||
value: 'url("te)st")',
|
||||
args: ['te)st'],
|
||||
image: null
|
||||
},
|
||||
'test quoted'
|
||||
);
|
||||
|
||||
test_parse_background_image(
|
||||
'url("te,st")',
|
||||
{
|
||||
prefix: '',
|
||||
method: 'url',
|
||||
value: 'url("te,st")',
|
||||
args: ['te,st'],
|
||||
image: null
|
||||
},
|
||||
'test quoted'
|
||||
);
|
||||
|
||||
test_parse_background_image(
|
||||
'url(te,st)',
|
||||
{
|
||||
prefix: '',
|
||||
method: 'url',
|
||||
value: 'url(te,st)',
|
||||
args: ['te,st'],
|
||||
image: null
|
||||
},
|
||||
'test quoted'
|
||||
);
|
||||
|
||||
test_parse_background_image(
|
||||
'url(test)',
|
||||
{
|
||||
prefix: '',
|
||||
method: 'url',
|
||||
value: 'url(test)',
|
||||
args: ['test'],
|
||||
image: null
|
||||
},
|
||||
'basic url'
|
||||
);
|
||||
|
||||
test_parse_background_image(
|
||||
'url("test")',
|
||||
{
|
||||
prefix: '',
|
||||
method: 'url',
|
||||
value: 'url("test")',
|
||||
args: ['test'],
|
||||
image: null
|
||||
},
|
||||
'quoted url'
|
||||
);
|
||||
|
||||
test_parse_background_image(
|
||||
'url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)',
|
||||
{
|
||||
prefix: '',
|
||||
method: 'url',
|
||||
value:
|
||||
'url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)',
|
||||
args: [
|
||||
'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7'
|
||||
],
|
||||
image: null
|
||||
},
|
||||
'data url'
|
||||
);
|
||||
|
||||
test_parse_background_image(
|
||||
'linear-gradient(red,black)',
|
||||
{
|
||||
prefix: '',
|
||||
method: 'linear-gradient',
|
||||
value: 'linear-gradient(red,black)',
|
||||
args: ['red', 'black'],
|
||||
image: null
|
||||
},
|
||||
'linear-gradient'
|
||||
);
|
||||
|
||||
test_parse_background_image(
|
||||
'linear-gradient(top,rgb(255,0,0),rgb(0,0,0))',
|
||||
{
|
||||
prefix: '',
|
||||
method: 'linear-gradient',
|
||||
value: 'linear-gradient(top,rgb(255,0,0),rgb(0,0,0))',
|
||||
args: ['top', 'rgb(255,0,0)', 'rgb(0,0,0)'],
|
||||
image: null
|
||||
},
|
||||
'linear-gradient w/ rgb()'
|
||||
);
|
||||
|
||||
test_parse_background_image(
|
||||
'-webkit-linear-gradient(red,black)',
|
||||
{
|
||||
prefix: '-webkit-',
|
||||
method: 'linear-gradient',
|
||||
value: '-webkit-linear-gradient(red,black)',
|
||||
args: ['red', 'black'],
|
||||
image: null
|
||||
},
|
||||
'prefixed linear-gradient'
|
||||
);
|
||||
|
||||
test_parse_background_image(
|
||||
'linear-gradient(red,black), url(test), url("test"),\n none, ',
|
||||
[
|
||||
{
|
||||
prefix: '',
|
||||
method: 'linear-gradient',
|
||||
value: 'linear-gradient(red,black)',
|
||||
args: ['red', 'black'],
|
||||
image: null
|
||||
},
|
||||
{prefix: '', method: 'url', value: 'url(test)', args: ['test'], image: null},
|
||||
{prefix: '', method: 'url', value: 'url("test")', args: ['test'], image: null},
|
||||
{prefix: '', method: 'none', value: 'none', args: [], image: null}
|
||||
],
|
||||
'multiple backgrounds'
|
||||
);
|
||||
|
||||
function test_parse_background_image(value, expected, name) {
|
||||
it(name, function() {
|
||||
expect(html2canvas.utils.parseBackgrounds(value)).to.eql(
|
||||
Array.isArray(expected) ? expected : [expected]
|
||||
);
|
||||
});
|
||||
}
|
||||
});
|
@ -1,166 +0,0 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Mocha Tests</title>
|
||||
<link rel="stylesheet" href="lib/mocha.css" />
|
||||
<script src="../../node_modules/bluebird/js/browser/bluebird.js"></script>
|
||||
<script src="../../dist/html2canvas.js"></script>
|
||||
<script src="../assets/jquery-1.6.2.js"></script>
|
||||
<script src="lib/expect.js"></script>
|
||||
<script src="lib/mocha.js"></script>
|
||||
<style>
|
||||
.block {
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="mocha"></div>
|
||||
<script>mocha.setup('bdd')</script>
|
||||
<div id="block1" class="block">
|
||||
<input type="text" value="text" />
|
||||
</div>
|
||||
<div id="block2" class="block">
|
||||
<input type="password" value="password" />
|
||||
</div>
|
||||
<div id="block3" class="block">
|
||||
<input type="text" value="text" />
|
||||
</div>
|
||||
|
||||
<div id="block4" class="block">
|
||||
<textarea>text</textarea>
|
||||
</div>
|
||||
|
||||
<div id="block5" class="block">
|
||||
<select>
|
||||
<option value="1">1</option>
|
||||
<option value="2" selected>2</option>
|
||||
<option value="3">3</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div id="green-block"></div>
|
||||
<script>
|
||||
var CanvasRenderer = html2canvas.CanvasRenderer;
|
||||
|
||||
describe("Rendering input values", function() {
|
||||
it("uses default value for input[type='text']", function(done) {
|
||||
CanvasRenderer.prototype.text = function(text) {
|
||||
expect(text).to.equal('text');
|
||||
};
|
||||
html2canvas(document.querySelector("#block1"), {renderer: CanvasRenderer, strict: true}).then(function(canvas) {
|
||||
expect(canvas.width).to.equal(200);
|
||||
expect(canvas.height).to.equal(200);
|
||||
done();
|
||||
}).catch(function(error) {
|
||||
done(error);
|
||||
});
|
||||
});
|
||||
|
||||
it("uses transformed value for input[type='password']", function(done) {
|
||||
var count = 0;
|
||||
CanvasRenderer.prototype.text = function(text) {
|
||||
expect(text).to.equal('•');
|
||||
count++;
|
||||
};
|
||||
html2canvas(document.querySelector("#block2"), {renderer: CanvasRenderer, strict: true}).then(function(canvas) {
|
||||
expect(canvas.width).to.equal(200);
|
||||
expect(canvas.height).to.equal(200);
|
||||
expect(count).to.equal("password".length);
|
||||
done();
|
||||
}).catch(function(error) {
|
||||
done(error);
|
||||
});
|
||||
});
|
||||
|
||||
it("used property and not attribute for rendering", function(done) {
|
||||
document.querySelector("#block3 input").value = 'updated';
|
||||
|
||||
CanvasRenderer.prototype.text = function(text) {
|
||||
expect(text).to.equal('updated');
|
||||
};
|
||||
html2canvas(document.querySelector("#block3"), {renderer: CanvasRenderer, strict: true}).then(function(canvas) {
|
||||
expect(canvas.width).to.equal(200);
|
||||
expect(canvas.height).to.equal(200);
|
||||
done();
|
||||
}).catch(function(error) {
|
||||
done(error);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Rendering textarea values", function() {
|
||||
it("uses default value correctly", function(done) {
|
||||
CanvasRenderer.prototype.text = function(text) {
|
||||
expect(text).to.equal('text');
|
||||
};
|
||||
html2canvas(document.querySelector("#block4"), {renderer: CanvasRenderer, strict: true}).then(function(canvas) {
|
||||
expect(canvas.width).to.equal(200);
|
||||
expect(canvas.height).to.equal(200);
|
||||
done();
|
||||
}).catch(function(error) {
|
||||
done(error);
|
||||
});
|
||||
});
|
||||
|
||||
it("used property and not attribute for rendering", function(done) {
|
||||
document.querySelector("#block4 textarea").value = 'updated';
|
||||
|
||||
CanvasRenderer.prototype.text = function(text) {
|
||||
expect(text).to.equal('updated');
|
||||
};
|
||||
html2canvas(document.querySelector("#block4"), {renderer: CanvasRenderer, strict: true}).then(function(canvas) {
|
||||
expect(canvas.width).to.equal(200);
|
||||
expect(canvas.height).to.equal(200);
|
||||
done();
|
||||
}).catch(function(error) {
|
||||
done(error);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("Select values", function() {
|
||||
it("uses default value correctly", function(done) {
|
||||
CanvasRenderer.prototype.text = function(text) {
|
||||
expect(text).to.equal('2');
|
||||
};
|
||||
html2canvas(document.querySelector("#block5"), {renderer: CanvasRenderer, strict: true}).then(function(canvas) {
|
||||
expect(canvas.width).to.equal(200);
|
||||
expect(canvas.height).to.equal(200);
|
||||
done();
|
||||
}).catch(function(error) {
|
||||
done(error);
|
||||
});
|
||||
});
|
||||
|
||||
it("used property and not attribute for rendering", function(done) {
|
||||
document.querySelector("#block5 select").value = '3';
|
||||
|
||||
CanvasRenderer.prototype.text = function(text) {
|
||||
expect(text).to.equal('3');
|
||||
};
|
||||
html2canvas(document.querySelector("#block5"), {renderer: CanvasRenderer, strict: true}).then(function(canvas) {
|
||||
expect(canvas.width).to.equal(200);
|
||||
expect(canvas.height).to.equal(200);
|
||||
done();
|
||||
}).catch(function(error) {
|
||||
done(error);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
mocha.checkLeaks();
|
||||
mocha.globals(['jQuery']);
|
||||
if (window.mochaPhantomJS) {
|
||||
mochaPhantomJS.run();
|
||||
}
|
||||
else {
|
||||
mocha.run();
|
||||
}
|
||||
mocha.suite.afterAll(function() {
|
||||
document.body.setAttribute('data-complete', 'true');
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -1,145 +0,0 @@
|
||||
describe('Gradients', function() {
|
||||
var expected = [
|
||||
{
|
||||
method: 'linear-gradient',
|
||||
args: ['left', ' rgb(255, 0, 0)', ' rgb(255, 255, 0)', ' rgb(0, 255, 0)']
|
||||
},
|
||||
{
|
||||
method: 'linear-gradient',
|
||||
args: ['left', ' red', ' rgb(255, 255, 0)', ' rgb(0, 255, 0)']
|
||||
},
|
||||
{
|
||||
method: 'linear-gradient',
|
||||
args: [
|
||||
'left',
|
||||
' rgb(206, 219, 233) 0%',
|
||||
' rgb(170, 197, 222) 17%',
|
||||
' rgb(97, 153, 199) 50%',
|
||||
' rgb(58, 132, 195) 51%',
|
||||
' rgb(65, 154, 214) 59%',
|
||||
' rgb(75, 184, 240) 71%',
|
||||
' rgb(58, 139, 194) 84%',
|
||||
' rgb(38, 85, 139) 100%'
|
||||
]
|
||||
},
|
||||
{
|
||||
method: 'linear-gradient',
|
||||
args: [
|
||||
'left',
|
||||
' rgb(206, 219, 233) 0%',
|
||||
' rgb(170, 197, 222) 17px',
|
||||
' rgb(97, 153, 199) 50%',
|
||||
' rgb(58, 132, 195) 51px',
|
||||
' rgb(65, 154, 214) 59%',
|
||||
' rgb(75, 184, 240) 71px',
|
||||
' rgb(58, 139, 194) 84%',
|
||||
' rgb(38, 85, 139) 100px'
|
||||
]
|
||||
},
|
||||
{
|
||||
method: 'gradient',
|
||||
args: [
|
||||
'linear',
|
||||
' 50% 0%',
|
||||
' 50% 100%',
|
||||
' from(rgb(240, 183, 161))',
|
||||
' color-stop(0.5, rgb(140, 51, 16))',
|
||||
' color-stop(0.51, rgb(117, 34, 1))',
|
||||
' to(rgb(191, 110, 78))'
|
||||
]
|
||||
},
|
||||
{
|
||||
method: 'gradient',
|
||||
args: [
|
||||
'linear',
|
||||
' 50% 0%',
|
||||
' 50% 100%',
|
||||
' from(rgb(255, 0, 0))',
|
||||
' color-stop(0.314159, green)',
|
||||
' color-stop(0.51, rgb(0, 0, 255))',
|
||||
// temporary workaround for Blink/WebKit bug: crbug.com/453414
|
||||
//" to(rgba(0, 0, 0, 0.5))"
|
||||
' to(rgba(0, 0, 0, 0))'
|
||||
]
|
||||
},
|
||||
{
|
||||
method: 'linear-gradient',
|
||||
args: ['0deg', ' rgb(221, 221, 221)', ' rgb(221, 221, 221) 50%', ' transparent 50%']
|
||||
},
|
||||
{
|
||||
method: 'radial-gradient',
|
||||
args: [
|
||||
'75% 19%',
|
||||
' ellipse closest-side',
|
||||
' rgb(171, 171, 171)',
|
||||
' rgb(0, 0, 255) 33%',
|
||||
' rgb(153, 31, 31) 100%'
|
||||
]
|
||||
},
|
||||
{
|
||||
method: 'radial-gradient',
|
||||
args: [
|
||||
'75% 19%',
|
||||
' ellipse closest-corner',
|
||||
' rgb(171, 171, 171)',
|
||||
' rgb(0, 0, 255) 33%',
|
||||
' rgb(153, 31, 31) 100%'
|
||||
]
|
||||
},
|
||||
{
|
||||
method: 'radial-gradient',
|
||||
args: [
|
||||
'75% 19%',
|
||||
' ellipse farthest-side',
|
||||
' rgb(171, 171, 171)',
|
||||
' rgb(0, 0, 255) 33%',
|
||||
' rgb(153, 31, 31) 100%'
|
||||
]
|
||||
},
|
||||
{
|
||||
method: 'radial-gradient',
|
||||
args: [
|
||||
'75% 19%',
|
||||
' ellipse farthest-corner',
|
||||
' rgb(171, 171, 171)',
|
||||
' rgb(0, 0, 255) 33%',
|
||||
' rgb(153, 31, 31) 100%'
|
||||
]
|
||||
},
|
||||
{
|
||||
method: 'radial-gradient',
|
||||
args: [
|
||||
'75% 19%',
|
||||
' ellipse contain',
|
||||
' rgb(171, 171, 171)',
|
||||
' rgb(0, 0, 255) 33%',
|
||||
' rgb(153, 31, 31) 100%'
|
||||
]
|
||||
},
|
||||
{
|
||||
method: 'radial-gradient',
|
||||
args: [
|
||||
'75% 19%',
|
||||
' ellipse cover',
|
||||
' rgb(171, 171, 171)',
|
||||
' rgb(0, 0, 255) 33%',
|
||||
' rgb(153, 31, 31) 100%'
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
[].slice
|
||||
.call(document.querySelectorAll('#backgroundGradients div'), 0)
|
||||
.forEach(function(node, i) {
|
||||
var container = new html2canvas.NodeContainer(node, null);
|
||||
var value = container.css('backgroundImage');
|
||||
it(value, function() {
|
||||
var parsedBackground = html2canvas.utils.parseBackgrounds(value);
|
||||
if (parsedBackground[0].args[0] === '0% 50%') {
|
||||
parsedBackground[0].args[0] = 'left';
|
||||
}
|
||||
expect(parsedBackground[0].args).to.eql(expected[i].args);
|
||||
expect(parsedBackground[0].method).to.eql(expected[i].method);
|
||||
});
|
||||
});
|
||||
});
|
@ -1,67 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head lang="en">
|
||||
<meta charset="UTF-8">
|
||||
<title>Proxy tests</title>
|
||||
<link rel="stylesheet" href="lib/mocha.css" />
|
||||
<script src="../../node_modules/bluebird/js/browser/bluebird.js"></script>
|
||||
<script src="../assets/jquery-1.6.2.js"></script>
|
||||
<script src="lib/expect.js"></script>
|
||||
<script src="lib/mocha.js"></script>
|
||||
<style>
|
||||
#block {
|
||||
background: red;
|
||||
}
|
||||
|
||||
#block.class {
|
||||
background: green;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div style="width: 200px; height:200px;" id="block"></div>
|
||||
<script src="../../dist/html2canvas.js"></script>
|
||||
<script src="clone.js"></script>
|
||||
<div id="mocha"></div>
|
||||
<script>mocha.setup('bdd')</script>
|
||||
<script>
|
||||
// https://github.com/niklasvh/html2canvas/issues/503
|
||||
describe("Document clone should not re-execute javascript", function() {
|
||||
it("with mutating className", function (done) {
|
||||
this.timeout(10000);
|
||||
html2canvas(document.querySelector("#block")).then(function (canvas) {
|
||||
expect(canvas.width).to.equal(200);
|
||||
expect(canvas.height).to.equal(200);
|
||||
validCanvasPixels(canvas);
|
||||
done();
|
||||
}).catch(function (error) {
|
||||
done(error);
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
function validCanvasPixels(canvas) {
|
||||
var ctx = canvas.getContext("2d");
|
||||
var data = ctx.getImageData(0, 0, canvas.width, canvas.height).data;
|
||||
for (var i = 0, len = data.length; i < len; i+=4) {
|
||||
if (data[i] !== 0 || data[i+1] !== 128 || data[i+2] !== 0 || data[i+3] !== 255) {
|
||||
expect().fail("Invalid canvas data");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mocha.checkLeaks();
|
||||
mocha.globals(['jQuery']);
|
||||
if (window.mochaPhantomJS) {
|
||||
mochaPhantomJS.run();
|
||||
}
|
||||
else {
|
||||
mocha.run();
|
||||
}
|
||||
mocha.suite.afterAll(function() {
|
||||
document.body.setAttribute('data-complete', 'true');
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -1,23 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head lang="en">
|
||||
<meta charset="UTF-8">
|
||||
<title></title>
|
||||
<style>
|
||||
html, body {
|
||||
background: green;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
.invalid {
|
||||
margin-top: 350px;
|
||||
height: 500px;
|
||||
background: red;
|
||||
display: block;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="invalid"> </div>
|
||||
</body>
|
||||
</html>
|
@ -1,23 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head lang="en">
|
||||
<meta charset="UTF-8">
|
||||
<title></title>
|
||||
<style>
|
||||
|
||||
html, body {
|
||||
background: red;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
.valid {
|
||||
margin-top: 350px;
|
||||
height: 350px;
|
||||
background: green;
|
||||
display: block;
|
||||
margin-bottom: 500px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body><div class="valid"> </div></body>
|
||||
</html>
|
@ -1,21 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head lang="en">
|
||||
<meta charset="UTF-8">
|
||||
<title></title>
|
||||
<style>
|
||||
|
||||
html, body {
|
||||
background: red;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
.valid {
|
||||
height: 350px;
|
||||
background: green;
|
||||
display: block;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body><div class="valid"> </div></body>
|
||||
</html>
|
File diff suppressed because it is too large
Load Diff
@ -1,270 +0,0 @@
|
||||
@charset "utf-8";
|
||||
|
||||
body {
|
||||
margin:0;
|
||||
}
|
||||
|
||||
#mocha {
|
||||
font: 20px/1.5 "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
margin: 60px 50px;
|
||||
}
|
||||
|
||||
#mocha ul,
|
||||
#mocha li {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
#mocha ul {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
#mocha h1,
|
||||
#mocha h2 {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#mocha h1 {
|
||||
margin-top: 15px;
|
||||
font-size: 1em;
|
||||
font-weight: 200;
|
||||
}
|
||||
|
||||
#mocha h1 a {
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
#mocha h1 a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
#mocha .suite .suite h1 {
|
||||
margin-top: 0;
|
||||
font-size: .8em;
|
||||
}
|
||||
|
||||
#mocha .hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#mocha h2 {
|
||||
font-size: 12px;
|
||||
font-weight: normal;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#mocha .suite {
|
||||
margin-left: 15px;
|
||||
}
|
||||
|
||||
#mocha .test {
|
||||
margin-left: 15px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#mocha .test.pending:hover h2::after {
|
||||
content: '(pending)';
|
||||
font-family: arial, sans-serif;
|
||||
}
|
||||
|
||||
#mocha .test.pass.medium .duration {
|
||||
background: #c09853;
|
||||
}
|
||||
|
||||
#mocha .test.pass.slow .duration {
|
||||
background: #b94a48;
|
||||
}
|
||||
|
||||
#mocha .test.pass::before {
|
||||
content: '✓';
|
||||
font-size: 12px;
|
||||
display: block;
|
||||
float: left;
|
||||
margin-right: 5px;
|
||||
color: #00d6b2;
|
||||
}
|
||||
|
||||
#mocha .test.pass .duration {
|
||||
font-size: 9px;
|
||||
margin-left: 5px;
|
||||
padding: 2px 5px;
|
||||
color: #fff;
|
||||
-webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.2);
|
||||
-moz-box-shadow: inset 0 1px 1px rgba(0,0,0,.2);
|
||||
box-shadow: inset 0 1px 1px rgba(0,0,0,.2);
|
||||
-webkit-border-radius: 5px;
|
||||
-moz-border-radius: 5px;
|
||||
-ms-border-radius: 5px;
|
||||
-o-border-radius: 5px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
#mocha .test.pass.fast .duration {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#mocha .test.pending {
|
||||
color: #0b97c4;
|
||||
}
|
||||
|
||||
#mocha .test.pending::before {
|
||||
content: '◦';
|
||||
color: #0b97c4;
|
||||
}
|
||||
|
||||
#mocha .test.fail {
|
||||
color: #c00;
|
||||
}
|
||||
|
||||
#mocha .test.fail pre {
|
||||
color: black;
|
||||
}
|
||||
|
||||
#mocha .test.fail::before {
|
||||
content: '✖';
|
||||
font-size: 12px;
|
||||
display: block;
|
||||
float: left;
|
||||
margin-right: 5px;
|
||||
color: #c00;
|
||||
}
|
||||
|
||||
#mocha .test pre.error {
|
||||
color: #c00;
|
||||
max-height: 300px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
/**
|
||||
* (1): approximate for browsers not supporting calc
|
||||
* (2): 42 = 2*15 + 2*10 + 2*1 (padding + margin + border)
|
||||
* ^^ seriously
|
||||
*/
|
||||
#mocha .test pre {
|
||||
display: block;
|
||||
float: left;
|
||||
clear: left;
|
||||
font: 12px/1.5 monaco, monospace;
|
||||
margin: 5px;
|
||||
padding: 15px;
|
||||
border: 1px solid #eee;
|
||||
max-width: 85%; /*(1)*/
|
||||
max-width: calc(100% - 42px); /*(2)*/
|
||||
word-wrap: break-word;
|
||||
border-bottom-color: #ddd;
|
||||
-webkit-border-radius: 3px;
|
||||
-webkit-box-shadow: 0 1px 3px #eee;
|
||||
-moz-border-radius: 3px;
|
||||
-moz-box-shadow: 0 1px 3px #eee;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
#mocha .test h2 {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#mocha .test a.replay {
|
||||
position: absolute;
|
||||
top: 3px;
|
||||
right: 0;
|
||||
text-decoration: none;
|
||||
vertical-align: middle;
|
||||
display: block;
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
line-height: 15px;
|
||||
text-align: center;
|
||||
background: #eee;
|
||||
font-size: 15px;
|
||||
-moz-border-radius: 15px;
|
||||
border-radius: 15px;
|
||||
-webkit-transition: opacity 200ms;
|
||||
-moz-transition: opacity 200ms;
|
||||
transition: opacity 200ms;
|
||||
opacity: 0.3;
|
||||
color: #888;
|
||||
}
|
||||
|
||||
#mocha .test:hover a.replay {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
#mocha-report.pass .test.fail {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#mocha-report.fail .test.pass {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#mocha-report.pending .test.pass,
|
||||
#mocha-report.pending .test.fail {
|
||||
display: none;
|
||||
}
|
||||
#mocha-report.pending .test.pass.pending {
|
||||
display: block;
|
||||
}
|
||||
|
||||
#mocha-error {
|
||||
color: #c00;
|
||||
font-size: 1.5em;
|
||||
font-weight: 100;
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
|
||||
#mocha-stats {
|
||||
position: fixed;
|
||||
top: 15px;
|
||||
right: 10px;
|
||||
font-size: 12px;
|
||||
margin: 0;
|
||||
color: #888;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
#mocha-stats .progress {
|
||||
float: right;
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
#mocha-stats em {
|
||||
color: black;
|
||||
}
|
||||
|
||||
#mocha-stats a {
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
#mocha-stats a:hover {
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
|
||||
#mocha-stats li {
|
||||
display: inline-block;
|
||||
margin: 0 5px;
|
||||
list-style: none;
|
||||
padding-top: 11px;
|
||||
}
|
||||
|
||||
#mocha-stats canvas {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
#mocha code .comment { color: #ddd; }
|
||||
#mocha code .init { color: #2f6fad; }
|
||||
#mocha code .string { color: #5890ad; }
|
||||
#mocha code .keyword { color: #8a6343; }
|
||||
#mocha code .number { color: #2f6fad; }
|
||||
|
||||
@media screen and (max-device-width: 480px) {
|
||||
#mocha {
|
||||
margin: 60px 0px;
|
||||
}
|
||||
|
||||
#mocha #stats {
|
||||
position: absolute;
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -1,99 +0,0 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Mocha Tests</title>
|
||||
<link rel="stylesheet" href="lib/mocha.css" />
|
||||
<script src="../../node_modules/bluebird/js/browser/bluebird.js"></script>
|
||||
<script src="../../dist/html2canvas.js"></script>
|
||||
<script src="../assets/jquery-1.6.2.js"></script>
|
||||
<script src="lib/expect.js"></script>
|
||||
<script src="lib/mocha.js"></script>
|
||||
<style>
|
||||
#block {
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
}
|
||||
#green-block {
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
background: green;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="mocha"></div>
|
||||
<div id="block"></div>
|
||||
<div id="green-block"></div>
|
||||
<script>mocha.setup('bdd')</script>
|
||||
<script>
|
||||
describe("Multiple renders", function() {
|
||||
it("render correctly", function(done) {
|
||||
this.timeout(10000);
|
||||
var d = 0;
|
||||
var count = 3;
|
||||
for (var i = 0; i < count; i++) {
|
||||
html2canvas(document.querySelector('#green-block')).then(function (canvas) {
|
||||
expect(canvas.width).to.equal(200);
|
||||
expect(canvas.height).to.equal(200);
|
||||
validCanvasPixels(canvas);
|
||||
canvas.width = canvas.height = 10;
|
||||
d++;
|
||||
if (d === count) {
|
||||
done();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
it("render correctly when non sequential", function(done) {
|
||||
this.timeout(10000);
|
||||
var d = 0;
|
||||
var count = 3;
|
||||
for (var i = 0; i < count; i++) {
|
||||
html2canvas(document.querySelector('#block'), {onclone: function(document) {
|
||||
return new Promise(function(resolve) {
|
||||
document.querySelector('#block').style.backgroundColor = 'green';
|
||||
setTimeout(function() {
|
||||
resolve();
|
||||
}, 100);
|
||||
});
|
||||
}}).then(function (canvas) {
|
||||
expect(canvas.width).to.equal(200);
|
||||
expect(canvas.height).to.equal(200);
|
||||
validCanvasPixels(canvas);
|
||||
canvas.width = canvas.height = 10;
|
||||
d++;
|
||||
if (d === count) {
|
||||
done();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
function validCanvasPixels(canvas) {
|
||||
var ctx = canvas.getContext("2d");
|
||||
var data = ctx.getImageData(0, 0, canvas.width, canvas.height).data;
|
||||
for (var i = 0, len = 200*199*4; i < len; i+=4) {
|
||||
if (data[i] !== 0 || data[i+1] !== 128 || data[i+2] !== 0 || data[i+3] !== 255) {
|
||||
console.log(i, data[i], data[i+1], data[i+2], data[i+3]);
|
||||
expect().fail("Invalid canvas data");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mocha.suite.afterAll(function() {
|
||||
document.body.setAttribute('data-complete', 'true');
|
||||
});
|
||||
|
||||
mocha.checkLeaks();
|
||||
mocha.globals(['jQuery']);
|
||||
if (window.mochaPhantomJS) {
|
||||
mochaPhantomJS.run();
|
||||
}
|
||||
else {
|
||||
mocha.run();
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -1,98 +0,0 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Mocha Tests</title>
|
||||
<link rel="stylesheet" href="lib/mocha.css" />
|
||||
<script src="../../node_modules/bluebird/js/browser/bluebird.js"></script>
|
||||
<script src="../../dist/html2canvas.js"></script>
|
||||
<script src="../assets/jquery-1.6.2.js"></script>
|
||||
<script src="lib/expect.js"></script>
|
||||
<script src="lib/mocha.js"></script>
|
||||
<style>
|
||||
#block2 {
|
||||
background: red;
|
||||
}
|
||||
|
||||
.my-css-class #block2 {
|
||||
background: green;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="mocha"></div>
|
||||
<script>mocha.setup('bdd')</script>
|
||||
<div style="background: red; width: 200px; height:200px;" id="block"></div>
|
||||
<div style="width: 200px; height:200px;" id="block2"></div>
|
||||
<script>
|
||||
describe("options.onclone", function() {
|
||||
it("with a function", function(done) {
|
||||
html2canvas(document.querySelector("#block"), {onclone: function(document) {
|
||||
document.querySelector("#block").style.background = "green";
|
||||
}}).then(function(canvas) {
|
||||
expect(canvas.width).to.equal(200);
|
||||
expect(canvas.height).to.equal(200);
|
||||
expect(document.querySelector("#block").style.backgroundColor).to.equal("red");
|
||||
validCanvasPixels(canvas);
|
||||
done();
|
||||
}).catch(function(error) {
|
||||
done(error);
|
||||
});
|
||||
});
|
||||
|
||||
it("with a promise", function(done) {
|
||||
html2canvas(document.querySelector("#block"), {onclone: function(document) {
|
||||
return new Promise(function(resolve) {
|
||||
setTimeout(function() {
|
||||
document.querySelector("#block").style.background = "green";
|
||||
resolve();
|
||||
}, 500);
|
||||
});
|
||||
}}).then(function(canvas) {
|
||||
expect(canvas.width).to.equal(200);
|
||||
expect(canvas.height).to.equal(200);
|
||||
expect(document.querySelector("#block").style.backgroundColor).to.equal("red");
|
||||
validCanvasPixels(canvas);
|
||||
done();
|
||||
}).catch(function(error) {
|
||||
done(error);
|
||||
});
|
||||
});
|
||||
|
||||
it("add class to node", function(done) {
|
||||
html2canvas(document.querySelector("#block2"), {onclone: function(document) {
|
||||
document.documentElement.className = "my-css-class";
|
||||
}}).then(function(canvas) {
|
||||
expect(canvas.width).to.equal(200);
|
||||
expect(canvas.height).to.equal(200);
|
||||
validCanvasPixels(canvas);
|
||||
done();
|
||||
}).catch(function(error) {
|
||||
done(error);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function validCanvasPixels(canvas) {
|
||||
var ctx = canvas.getContext("2d");
|
||||
var data = ctx.getImageData(0, 0, canvas.width, canvas.height).data;
|
||||
for (var i = 0, len = data.length; i < len; i+=4) {
|
||||
if (data[i] !== 0 || data[i+1] !== 128 || data[i+2] !== 0 || data[i+3] !== 255) {
|
||||
expect().fail("Invalid canvas data");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mocha.checkLeaks();
|
||||
mocha.globals(['jQuery']);
|
||||
if (window.mochaPhantomJS) {
|
||||
mochaPhantomJS.run();
|
||||
}
|
||||
else {
|
||||
mocha.run();
|
||||
}
|
||||
mocha.suite.afterAll(function() {
|
||||
document.body.setAttribute('data-complete', 'true');
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -1,235 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Mocha Tests</title>
|
||||
<link rel="stylesheet" href="lib/mocha.css" />
|
||||
<script src="../../dist/html2canvas.js"></script>
|
||||
<script src="../assets/jquery-1.6.2.js"></script>
|
||||
<script src="lib/expect.js"></script>
|
||||
<script src="lib/mocha.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="mocha"></div>
|
||||
<script>mocha.setup('bdd')</script>
|
||||
<div style="visibility: hidden">
|
||||
<div id="borders">Yep, here's some more.
|
||||
<div style="border-width: 1px 0;">Div 1</div>
|
||||
<div style="border-width: 1em 0;">Div 2</div>
|
||||
<div style="border-width: thin medium thick;">Some more divs</div>
|
||||
<div style="border-width: 5% 6px 12%;"></div> <!-- percentages aren't valid -->
|
||||
<div style="border-width: 5em 5ex 5in 5cm;"></div>
|
||||
<div style="border-width: 500em 500ex 500in 500cm;"></div>
|
||||
<div style="border-width: 5mm 5pt 5pc 5px;"></div>
|
||||
<div style="border-width: auto inherit;"></div>
|
||||
<div style="border-width: 500mm 500pt 500pc 500px;"></div>
|
||||
</div>
|
||||
|
||||
<div id="padding">
|
||||
<div style="padding: 1px 0;"></div>
|
||||
<div style="padding: 1em 0;"></div>
|
||||
<div style="padding: thin medium thick;"></div>
|
||||
<div style="padding: 5em 5ex 5in 5cm;"></div>
|
||||
<div style="padding: 500em 500ex 500in 500cm;"></div>
|
||||
<div style="padding: 5mm 5pt 5pc 5px;"></div>
|
||||
<div style="padding: 500mm 500pt 500pc 500px;"></div>
|
||||
<div style="padding: 1px 5%;"></div>
|
||||
<div style="padding: 15% 0 3%;"></div>
|
||||
</div>
|
||||
|
||||
<div id="textShadows">
|
||||
<div style=""></div>
|
||||
<div style="text-shadow: 1px 1px 1px"></div>
|
||||
<div style="text-shadow: 2px 2px rgb(2, 2, 2)"></div>
|
||||
<div style="text-shadow: 3px 3px rgba(2, 2, 2, .2)"></div>
|
||||
<div style="text-shadow: rgb(2, 2, 2) 4px 4px"></div>
|
||||
<div style="text-shadow: rgba(2, 2, 2, .2) 5px 5px"></div>
|
||||
<div style="text-shadow: rgb(2, 2, 2) 6px 6px, #222222 2px 2px"></div>
|
||||
<div style="text-shadow: 7px 7px rgba(2, 2, 2, .2), #222222 2px 2px"></div>
|
||||
</div>
|
||||
|
||||
<div id="backgroundPosition">
|
||||
<div style="background-position: 1px 0;"></div>
|
||||
<div style="background-position: 1em 0;"></div>
|
||||
<div style="background-position: thin medium;"></div>
|
||||
<div style="background-position: 5em 5ex;"></div>
|
||||
<div style="background-position: 5in 5cm;"></div>
|
||||
<div style="background-position: 500in 500cm;"></div>
|
||||
<div style="background-position: 500em 500ex;"></div>
|
||||
<div style="background-position: 5pc 5px;"></div>
|
||||
<div style="background-position: 500pc 500px;"></div>
|
||||
<div style="background-position: 5mm 5pt;"></div>
|
||||
<div style="background-position: 500mm 500pt;"></div>
|
||||
</div>
|
||||
|
||||
<div id="backgroundPositionPercentage">
|
||||
<div style="background-position: 5% 6px;"></div>
|
||||
<div style="background-position: center center;"></div>
|
||||
<div style="background-position: left bottom;"></div>
|
||||
</div>
|
||||
|
||||
<div id="backgroundGradients">
|
||||
<style scoped>
|
||||
.linearGradientSimple {
|
||||
/* FF 3.6+ */
|
||||
background: -moz-linear-gradient(left, #ff0000, #ffff00, #00ff00);
|
||||
/* Chrome,Safari4+ */
|
||||
background: -webkit-gradient(linear, left center, right center, color-stop(#ff0000), color-stop(#ffff00), color-stop(#00ff00));
|
||||
/* Chrome 10+, Safari 5.1+ */
|
||||
background: -webkit-linear-gradient(left, #ff0000, #ffff00, #00ff00);
|
||||
/* Opera 11.10+ */
|
||||
background: -o-linear-gradient(left, #ff0000, #ffff00, #00ff00);
|
||||
/* IE 10+ */
|
||||
background: -ms-linear-gradient(left, #ff0000, #ffff00, #00ff00);
|
||||
/* W3C */
|
||||
background: linear-gradient(left, #ff0000, #ffff00, #00ff00);
|
||||
}
|
||||
.linearGradientSimple2 {
|
||||
/* FF 3.6+ */
|
||||
background: -moz-linear-gradient(left, red, #ff0, #0f0);
|
||||
/* Chrome,Safari4+ */
|
||||
background: -webkit-gradient(linear, left center, right center, color-stop(red), color-stop(#ff0), color-stop(#0f0));
|
||||
/* Chrome 10+, Safari 5.1+ */
|
||||
background: -webkit-linear-gradient(left, red, #ff0, #0f0);
|
||||
/* Opera 11.10+ */
|
||||
background: -o-linear-gradient(left, red, #ff0, #0f0);
|
||||
/* IE 10+ */
|
||||
background: -ms-linear-gradient(left, red, #ff0, #0f0);
|
||||
/* W3C */
|
||||
background: linear-gradient(left, red, #ff0, #0f0);
|
||||
}
|
||||
.linearGradientWithStops {
|
||||
/* FF 3.6+ */
|
||||
background: -moz-linear-gradient(left, #cedbe9 0%, #aac5de 17%, #6199c7 50%, #3a84c3 51%, #419ad6 59%, #4bb8f0 71%, #3a8bc2 84%, #26558b 100%);
|
||||
/* Chrome, Safari 4+ */
|
||||
background: -webkit-gradient(linear, left center, right center, color-stop(0%, #cedbe9), color-stop(17%, #aac5de), color-stop(50%, #6199c7), color-stop(51%, #3a84c3), color-stop(59%, #419ad6), color-stop(71%, #4bb8f0), color-stop(84%, #3a8bc2), color-stop(100%, #26558b));
|
||||
/* Chrome 10+, Safari 5.1+ */
|
||||
background: -webkit-linear-gradient(left, #cedbe9 0%, #aac5de 17%, #6199c7 50%, #3a84c3 51%, #419ad6 59%, #4bb8f0 71%, #3a8bc2 84%, #26558b 100%);
|
||||
/* Opera 11.10+ */
|
||||
background: -o-linear-gradient(left, #cedbe9 0%, #aac5de 17%, #6199c7 50%, #3a84c3 51%, #419ad6 59%, #4bb8f0 71%, #3a8bc2 84%, #26558b 100%);
|
||||
/* IE 10+ */
|
||||
background: -ms-linear-gradient(left, #cedbe9 0%, #aac5de 17%, #6199c7 50%, #3a84c3 51%, #419ad6 59%, #4bb8f0 71%, #3a8bc2 84%, #26558b 100%);
|
||||
/* W3C */
|
||||
background: linear-gradient(left, #cedbe9 0%, #aac5de 17%, #6199c7 50%, #3a84c3 51%, #419ad6 59%, #4bb8f0 71%, #3a8bc2 84%, #26558b 100%);
|
||||
}
|
||||
.linearGradientWithPixelLengthStops {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
/* FF 3.6+ */
|
||||
background: -moz-linear-gradient(left, #cedbe9 0%, #aac5de 17px, #6199c7 50%, #3a84c3 51px, #419ad6 59%, #4bb8f0 71px, #3a8bc2 84%, #26558b 100px);
|
||||
/* Chrome, Safari 4+ */
|
||||
background: -webkit-gradient(linear, left center, right center, color-stop(0%, #cedbe9), color-stop(17px, #aac5de), color-stop(50%, #6199c7), color-stop(51%, #3a84c3), color-stop(59%, #419ad6), color-stop(71px, #4bb8f0), color-stop(84%, #3a8bc2), color-stop(100px, #26558b));
|
||||
/* Chrome 10+, Safari 5.1+ */
|
||||
background: -webkit-linear-gradient(left, #cedbe9 0%, #aac5de 17px, #6199c7 50%, #3a84c3 51px, #419ad6 59%, #4bb8f0 71px, #3a8bc2 84%, #26558b 100px);
|
||||
/* Opera 11.10+ */
|
||||
background: -o-linear-gradient(left, #cedbe9 0%, #aac5de 17px, #6199c7 50%, #3a84c3 51px, #419ad6 59%, #4bb8f0 71px, #3a8bc2 84%, #26558b 100px);
|
||||
/* IE 10+ */
|
||||
background: -ms-linear-gradient(left, #cedbe9 0%, #aac5de 17px, #6199c7 50%, #3a84c3 51px, #419ad6 59%, #4bb8f0 71px, #3a8bc2 84%, #26558b 100px);
|
||||
/* W3C */
|
||||
background: linear-gradient(left, #cedbe9 0%, #aac5de 17px, #6199c7 50%, #3a84c3 51px, #419ad6 59%, #4bb8f0 71px, #3a8bc2 84%, #26558b 100px);
|
||||
}
|
||||
.linearGradient5 {
|
||||
/* FF 3.6+ */
|
||||
background: -moz-linear-gradient(top, #f0b7a1 0%, #8c3310 50%, #752201 51%, #bf6e4e 100%);
|
||||
/* Chrome, Safari 4+ */
|
||||
background: -webkit-gradient(linear, center top, center bottom, color-stop(0%, #f0b7a1), color-stop(50%, #8c3310), color-stop(51%, #752201), color-stop(100%, #bf6e4e));
|
||||
/* Opera 11.10+ */
|
||||
background: -o-linear-gradient(top, #f0b7a1 0%, #8c3310 50%, #752201 51%, #bf6e4e 100%);
|
||||
/* IE 10+ */
|
||||
background: -ms-linear-gradient(top, #f0b7a1 0%, #8c3310 50%, #752201 51%, #bf6e4e 100%);
|
||||
/* W3C */
|
||||
background: linear-gradient(top, #f0b7a1 0%, #8c3310 50%, #752201 51%, #bf6e4e 100%);
|
||||
}
|
||||
.linearGradient6 {
|
||||
/* FF 3.6+ */
|
||||
background: -moz-linear-gradient(top, #F00 0, green 31.4159%, #0000fF 51%, rgba(0, 0, 0, 0.0) 100%);
|
||||
/* Chrome, Safari 4+ */
|
||||
background: -webkit-gradient(linear, center top, center bottom, color-stop(0, #F00), color-stop(31.4159%, green), color-stop(51%, #0000fF), color-stop(100%, rgba(0, 0, 0, 0.0)));
|
||||
/* Opera 11.10+ */
|
||||
background: -o-linear-gradient(top, #F00 0, green 31.4159%, #0000fF 51%, rgba(0, 0, 0, 0.0) 100%);
|
||||
/* IE 10+ */
|
||||
background: -ms-linear-gradient(top, #F00 0, green 31.4159%, #0000fF 51%, rgba(0, 0, 0, 0.0) 100%);
|
||||
/* W3C */
|
||||
background: linear-gradient(top, #F00 0, green 31.4159%, #0000fF 51%, rgba(0, 0, 0, 0.0) 100%);
|
||||
}
|
||||
.linearGradient7 {
|
||||
background: -webkit-linear-gradient(0deg, #ddd, #ddd 50%, transparent 50%);
|
||||
background: linear-gradient(0deg, #ddd, #ddd 50%, transparent 50%);
|
||||
}
|
||||
|
||||
.radialGradient {
|
||||
background: -moz-radial-gradient(75% 19%, ellipse closest-side, #ababab, #0000ff 33%,#991f1f 100%);
|
||||
background: -webkit-radial-gradient(75% 19%, ellipse closest-side, #ababab, #0000ff 33%,#991f1f 100%);
|
||||
background: -o-radial-gradient(75% 19%, ellipse closest-side, #ababab, #0000ff 33%,#991f1f 100%);
|
||||
background: -ms-radial-gradient(75% 19%, ellipse closest-side, #ababab, #0000ff 33%,#991f1f 100%);
|
||||
background: radial-gradient(75% 19%, ellipse closest-side, #ababab, #0000ff 33%,#991f1f 100%);
|
||||
}
|
||||
|
||||
.radialGradient2 {
|
||||
background: -moz-radial-gradient(75% 19%, ellipse closest-corner, #ababab, #0000ff 33%,#991f1f 100%);
|
||||
background: -webkit-radial-gradient(75% 19%, ellipse closest-corner, #ababab, #0000ff 33%,#991f1f 100%);
|
||||
background: -o-radial-gradient(75% 19%, ellipse closest-corner, #ababab, #0000ff 33%,#991f1f 100%);
|
||||
background: -ms-radial-gradient(75% 19%, ellipse closest-corner, #ababab, #0000ff 33%,#991f1f 100%);
|
||||
background: radial-gradient(75% 19%, ellipse closest-corner, #ababab, #0000ff 33%,#991f1f 100%);
|
||||
}
|
||||
.radialGradient3 {
|
||||
background: -moz-radial-gradient(75% 19%, ellipse farthest-side, #ababab, #0000ff 33%,#991f1f 100%);
|
||||
background: -webkit-radial-gradient(75% 19%, ellipse farthest-side, #ababab, #0000ff 33%,#991f1f 100%);
|
||||
background: -o-radial-gradient(75% 19%, ellipse farthest-side, #ababab, #0000ff 33%,#991f1f 100%);
|
||||
background: -ms-radial-gradient(75% 19%, ellipse farthest-side, #ababab, #0000ff 33%,#991f1f 100%);
|
||||
background: radial-gradient(75% 19%, ellipse farthest-side, #ababab, #0000ff 33%,#991f1f 100%)
|
||||
}
|
||||
.radialGradient4 {
|
||||
background: -moz-radial-gradient(75% 19%, ellipse farthest-corner, #ababab, #0000ff 33%,#991f1f 100%);
|
||||
background: -webkit-radial-gradient(75% 19%, ellipse farthest-corner, #ababab, #0000ff 33%,#991f1f 100%);
|
||||
background: -o-radial-gradient(75% 19%, ellipse farthest-corner, #ababab, #0000ff 33%,#991f1f 100%);
|
||||
background: -ms-radial-gradient(75% 19%, ellipse farthest-corner, #ababab, #0000ff 33%,#991f1f 100%);
|
||||
background: radial-gradient(75% 19%, ellipse farthest-corner, #ababab, #0000ff 33%,#991f1f 100%);
|
||||
}
|
||||
.radialGradient5 {
|
||||
background: -moz-radial-gradient(75% 19%, ellipse contain, #ababab, #0000ff 33%,#991f1f 100%);
|
||||
background: -webkit-radial-gradient(75% 19%, ellipse contain, #ababab, #0000ff 33%,#991f1f 100%);
|
||||
background: -o-radial-gradient(75% 19%, ellipse contain, #ababab, #0000ff 33%,#991f1f 100%);
|
||||
background: -ms-radial-gradient(75% 19%, ellipse contain, #ababab, #0000ff 33%,#991f1f 100%);
|
||||
background: radial-gradient(75% 19%, ellipse contain, #ababab, #0000ff 33%,#991f1f 100%);
|
||||
}
|
||||
.radialGradient6 {
|
||||
background: -moz-radial-gradient(75% 19%, ellipse cover, #ababab, #0000ff 33%,#991f1f 100%);
|
||||
background: -webkit-radial-gradient(75% 19%, ellipse cover, #ababab, #0000ff 33%,#991f1f 100%);
|
||||
background: -o-radial-gradient(75% 19%, ellipse cover, #ababab, #0000ff 33%,#991f1f 100%);
|
||||
background: -ms-radial-gradient(75% 19%, ellipse cover, #ababab, #0000ff 33%,#991f1f 100%);
|
||||
background: radial-gradient(75% 19%, ellipse cover, #ababab, #0000ff 33%,#991f1f 100%);
|
||||
}
|
||||
</style>
|
||||
<div class="linearGradientSimple"></div>
|
||||
<div class="linearGradientSimple2"></div>
|
||||
<div class="linearGradientWithStops"></div>
|
||||
<div class="linearGradientWithPixelLengthStops"></div>
|
||||
<div class="linearGradient5"></div>
|
||||
<div class="linearGradient6"></div>
|
||||
<div class="linearGradient7"></div>
|
||||
<div class="radialGradient"></div>
|
||||
<div class="radialGradient2"></div>
|
||||
<div class="radialGradient3"></div>
|
||||
<div class="radialGradient4"></div>
|
||||
<div class="radialGradient5"></div>
|
||||
<div class="radialGradient6"></div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="css.js"></script>
|
||||
<script src="gradients.js"></script>
|
||||
<script>
|
||||
mocha.checkLeaks();
|
||||
mocha.globals(['jQuery']);
|
||||
if (window.mochaPhantomJS) {
|
||||
mochaPhantomJS.run();
|
||||
}
|
||||
else {
|
||||
mocha.run();
|
||||
}
|
||||
mocha.suite.afterAll(function() {
|
||||
document.body.setAttribute('data-complete', 'true');
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -1,89 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head lang="en">
|
||||
<meta charset="UTF-8">
|
||||
<title>Proxy tests</title>
|
||||
<link rel="stylesheet" href="lib/mocha.css" />
|
||||
<script src="../../dist/html2canvas.js"></script>
|
||||
<script src="../assets/jquery-1.6.2.js"></script>
|
||||
<script src="lib/expect.js"></script>
|
||||
<script src="lib/mocha.js"></script>
|
||||
<style>
|
||||
#content {
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="mocha"></div>
|
||||
<script>mocha.setup('bdd')</script>
|
||||
<div id="content" style="display: inline-block;background: red;">
|
||||
<iframe src="http://localhost:8083/tests/mocha/iframe3.htm" style="border: 0; width: 200px; height: 200px;" scrolling="no"></iframe>
|
||||
</div>
|
||||
<script>
|
||||
describe("Proxy", function() {
|
||||
it("with iframe through proxy", function (done) {
|
||||
this.timeout(10000);
|
||||
html2canvas(document.querySelector("#content"), {proxy: 'http://localhost:8082'}).then(function (canvas) {
|
||||
validCanvasPixels(canvas);
|
||||
done();
|
||||
}).catch(function (error) {
|
||||
done(error);
|
||||
});
|
||||
});
|
||||
|
||||
it("with iframe without proxy", function (done) {
|
||||
html2canvas(document.querySelector("#content")).then(function (canvas) {
|
||||
expect(canvas.width).to.equal(200);
|
||||
expect(canvas.height).to.equal(200);
|
||||
done();
|
||||
}).catch(function (error) {
|
||||
done(error);
|
||||
});
|
||||
});
|
||||
|
||||
it("with url using proxy", function (done) {
|
||||
html2canvas("http://localhost:8083/tests/mocha/iframe3.htm", {proxy: 'http://localhost:8082', width: 200, height: 200, type: 'view'}).then(function (canvas) {
|
||||
expect(canvas.width).to.equal(200);
|
||||
expect(canvas.height).to.equal(200);
|
||||
done();
|
||||
}).catch(function (error) {
|
||||
done(error);
|
||||
});
|
||||
});
|
||||
|
||||
it("with url without proxy", function (done) {
|
||||
html2canvas("http://localhost:8083/tests/mocha/iframe3.htm").then(function () {
|
||||
done("Should throw error");
|
||||
}).catch(function (error) {
|
||||
expect(error).to.equal("Proxy must be used when rendering url");
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function validCanvasPixels(canvas) {
|
||||
var ctx = canvas.getContext("2d");
|
||||
var data = ctx.getImageData(0, 0, canvas.width, canvas.height).data;
|
||||
for (var i = 0, len = data.length; i < len; i+=4) {
|
||||
if (data[i] !== 0 || data[i+1] !== 128 || data[i+2] !== 0 || data[i+3] !== 255) {
|
||||
expect().fail("Invalid canvas data");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mocha.checkLeaks();
|
||||
mocha.globals(['jQuery']);
|
||||
if (window.mochaPhantomJS) {
|
||||
mochaPhantomJS.run();
|
||||
}
|
||||
else {
|
||||
mocha.run();
|
||||
}
|
||||
mocha.suite.afterAll(function() {
|
||||
document.body.setAttribute('data-complete', 'true');
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -1,117 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head lang="en">
|
||||
<meta charset="UTF-8">
|
||||
<title>Scrolling tests</title>
|
||||
<link rel="stylesheet" href="lib/mocha.css" />
|
||||
<script src="../../node_modules/bluebird/js/browser/bluebird.js"></script>
|
||||
<script src="../../dist/html2canvas.js"></script>
|
||||
<script src="../assets/jquery-1.6.2.js"></script>
|
||||
<script src="lib/expect.js"></script>
|
||||
<script src="lib/mocha.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="mocha"></div>
|
||||
<script>mocha.setup('bdd')</script>
|
||||
<div id="scroll-render" style="height: 200px; width: 200px;">
|
||||
<div style="height: 500px; width: 400px;overflow: scroll;" id="scrollable">
|
||||
<div style="height: 500px;background: red;"></div>
|
||||
<div style="height: 650px; background: green"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="height: 2200px"></div>
|
||||
<div style="height: 500px;background: green;" id="bottom-content"><a name="content"> </a></div>
|
||||
<script>
|
||||
describe("Scrolling", function() {
|
||||
it("with random scroll", function (done) {
|
||||
$(window).scrollTop(123);
|
||||
setTimeout(function() {
|
||||
html2canvas(document.body, {type: 'view'}).then(function () {
|
||||
expect($(window).scrollTop()).to.equal(123);
|
||||
done();
|
||||
}).catch(function (error) {
|
||||
done(error);
|
||||
});
|
||||
}, 0);
|
||||
});
|
||||
|
||||
it("with url anchor", function (done) {
|
||||
window.location.hash = "#content";
|
||||
setTimeout(function() {
|
||||
var top = $(window).scrollTop();
|
||||
html2canvas(document.body, {type: 'view'}).then(function () {
|
||||
var currentTop = $(window).scrollTop();
|
||||
window.location.hash = "";
|
||||
expect(currentTop).to.be.greaterThan(1500);
|
||||
if ((currentTop - top) !== 200) { // phantomjs issue
|
||||
expect(currentTop).to.equal(top);
|
||||
}
|
||||
done();
|
||||
}).catch(function (error) {
|
||||
done(error);
|
||||
});
|
||||
}, 0);
|
||||
});
|
||||
|
||||
it("with content scroll", function (done) {
|
||||
$("#scrollable").scrollTop(500);
|
||||
setTimeout(function() {
|
||||
html2canvas(document.querySelector("#scroll-render")).then(function (canvas) {
|
||||
expect($("#scrollable").scrollTop()).to.equal(500);
|
||||
expect(canvas.width).to.equal(200);
|
||||
expect(canvas.height).to.equal(200);
|
||||
validCanvasPixels(canvas);
|
||||
done();
|
||||
}).catch(function (error) {
|
||||
done(error);
|
||||
});
|
||||
}, 0);
|
||||
});
|
||||
|
||||
|
||||
it("with window scroll", function (done) {
|
||||
$(window).scrollTop(500);
|
||||
setTimeout(function() {
|
||||
console.log(document.querySelector("#bottom-content").getBoundingClientRect().top);
|
||||
html2canvas(document.querySelector("#bottom-content")).then(function (canvas) {
|
||||
expect($(window).scrollTop()).to.equal(500);
|
||||
validCanvasPixels(canvas);
|
||||
done();
|
||||
}).catch(function (error) {
|
||||
done(error);
|
||||
});
|
||||
}, 0);
|
||||
});
|
||||
});
|
||||
|
||||
function validCanvasPixels(canvas) {
|
||||
var ctx = canvas.getContext("2d");
|
||||
var data = ctx.getImageData(0, 0, canvas.width, canvas.height).data;
|
||||
for (var i = 0, len = 200*199*4; i < len; i+=4) {
|
||||
if (data[i] !== 0 || data[i+1] !== 128 || data[i+2] !== 0 || data[i+3] !== 255) {
|
||||
console.log(i, data[i], data[i+1], data[i+2], data[i+3]);
|
||||
expect().fail("Invalid canvas data");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
after(function() {
|
||||
if (history) {
|
||||
history.pushState("", document.title, window.location.pathname + window.location.search);
|
||||
}
|
||||
});
|
||||
|
||||
mocha.checkLeaks();
|
||||
mocha.globals(['jQuery']);
|
||||
if (window.mochaPhantomJS) {
|
||||
mochaPhantomJS.run();
|
||||
}
|
||||
else {
|
||||
mocha.run();
|
||||
}
|
||||
mocha.suite.afterAll(function() {
|
||||
document.body.setAttribute('data-complete', 'true');
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -1,99 +0,0 @@
|
||||
var wd = require('wd');
|
||||
var http = require('http');
|
||||
var https = require('https');
|
||||
var url = require('url');
|
||||
var path = require('path');
|
||||
var Promise = require('bluebird');
|
||||
var _ = require('lodash');
|
||||
var humanizeDuration = require('humanize-duration');
|
||||
var utils = require('../utils');
|
||||
var colors = utils.colors;
|
||||
var port = 8080;
|
||||
|
||||
function runTestWithRetries(browser, test, retries) {
|
||||
retries = retries || 0;
|
||||
return runTest(browser, test).timeout(30000).catch(Promise.TimeoutError, function() {
|
||||
if (retries < 3) {
|
||||
console.log(colors.violet, 'Retry', retries + 1, test);
|
||||
return runTestWithRetries(browser, test, retries + 1);
|
||||
} else {
|
||||
throw new Error("Couldn't run test after 3 retries");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function getResults(browser) {
|
||||
return function() {
|
||||
return Promise.props({
|
||||
dataUrl: browser
|
||||
.waitForElementByCss("body[data-complete='true']", 90000)
|
||||
.then(function() {
|
||||
return browser.elementsByCssSelector('.test.fail');
|
||||
})
|
||||
.then(function(nodes) {
|
||||
return Array.isArray(nodes)
|
||||
? Promise.map(nodes, function(node) {
|
||||
return browser.text(node).then(function(error) {
|
||||
return Promise.reject(error);
|
||||
});
|
||||
})
|
||||
: Promise.resolve([]);
|
||||
})
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
function runTest(browser, test) {
|
||||
return Promise.resolve(
|
||||
browser.then(utils.loadTestPage(browser, test, port)).then(getResults(browser))
|
||||
).cancellable();
|
||||
}
|
||||
|
||||
exports.tests = function(browsers, singleTest) {
|
||||
var path = 'tests/mocha';
|
||||
return (singleTest ? Promise.resolve([singleTest]) : utils.getTests(path)).then(function(
|
||||
tests
|
||||
) {
|
||||
return Promise.map(
|
||||
browsers,
|
||||
function(settings) {
|
||||
var name = [settings.browserName, settings.version, settings.platform].join('-');
|
||||
var count = 0;
|
||||
var browser = utils.initBrowser(settings);
|
||||
return Promise.using(browser, function() {
|
||||
return Promise.map(
|
||||
tests,
|
||||
function(test, index, total) {
|
||||
console.log(
|
||||
colors.green,
|
||||
'STARTING',
|
||||
'(' + ++count + '/' + total + ')',
|
||||
name,
|
||||
test,
|
||||
colors.clear
|
||||
);
|
||||
var start = Date.now();
|
||||
return runTestWithRetries(browser, test).then(function() {
|
||||
console.log(
|
||||
colors.green,
|
||||
'COMPLETE',
|
||||
humanizeDuration(Date.now() - start),
|
||||
'(' + count + '/' + total + ')',
|
||||
name,
|
||||
colors.clear
|
||||
);
|
||||
});
|
||||
},
|
||||
{concurrency: 1}
|
||||
)
|
||||
.settle()
|
||||
.catch(function(error) {
|
||||
console.error(colors.red, 'ERROR', name, error);
|
||||
throw error;
|
||||
});
|
||||
});
|
||||
},
|
||||
{concurrency: 3}
|
||||
);
|
||||
});
|
||||
};
|
50
tests/reftests/animation.html
Normal file
50
tests/reftests/animation.html
Normal file
@ -0,0 +1,50 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Animation</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<script type="text/javascript" src="../test.js"></script>
|
||||
<style>
|
||||
span {
|
||||
color:blue;
|
||||
}
|
||||
p {
|
||||
background-color: green;
|
||||
}
|
||||
div {
|
||||
background: red;
|
||||
border: 5px solid blue;
|
||||
animation: spin 3s linear 1s infinite;
|
||||
}
|
||||
body {
|
||||
font-family: Arial;
|
||||
}
|
||||
|
||||
@-webkit-keyframes spin {
|
||||
0% {
|
||||
-webkit-transform: rotate(0deg);
|
||||
transform: rotate(0deg);
|
||||
/* Firefox 16+, IE 10+, Opera */ }
|
||||
100% {
|
||||
-webkit-transform: rotate(360deg);
|
||||
transform: rotate(360deg);
|
||||
/* Firefox 16+, IE 10+, Opera */ } }
|
||||
|
||||
@keyframes spin {
|
||||
0% {
|
||||
-webkit-transform: rotate(0deg);
|
||||
transform: rotate(0deg);
|
||||
/* Firefox 16+, IE 10+, Opera */ }
|
||||
100% {
|
||||
-webkit-transform: rotate(360deg);
|
||||
transform: rotate(360deg);
|
||||
/* Firefox 16+, IE 10+, Opera */ } }
|
||||
</style>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div style="clip: rect(0px, 400px, 50px, 200px); ">Some inline text <span> followed by text in span </span> followed by more inline text.
|
||||
<p>Then a block level element.</p>
|
||||
Then more inline text.</div>
|
||||
</body>
|
||||
</html>
|
@ -20,13 +20,14 @@
|
||||
}
|
||||
|
||||
.medium div{
|
||||
width:200px;
|
||||
height:200px;
|
||||
width:100px;
|
||||
height:100px;
|
||||
float:left;
|
||||
margin:10px;
|
||||
border:20px solid transparent;
|
||||
border-width: 10px 20px 30px 40px;
|
||||
background: green;
|
||||
padding: 25px 15px;
|
||||
}
|
||||
|
||||
.small, .medium{
|
||||
@ -51,6 +52,8 @@
|
||||
<div class="medium">
|
||||
<div style="background:url(../../assets/image.jpg);background-clip: border-box; background-repeat: no-repeat;"></div>
|
||||
<div style="background:url(../../assets/image.jpg);background-clip: padding-box; background-repeat: repeat-y;"></div>
|
||||
<div style="background:url(../../assets/image.jpg);background-clip: padding-box; background-repeat: repeat-x;"></div>
|
||||
<div style="background:url(../../assets/image.jpg);background-clip: content-box; background-repeat: repeat-y;"></div>
|
||||
<div style="background:url(../../assets/image.jpg);background-clip: content-box; background-repeat: repeat-x;"></div>
|
||||
<div style="background:url(../../assets/image.jpg); background-repeat: no-repeat;"></div>
|
||||
</div>
|
||||
|
@ -49,7 +49,7 @@
|
||||
}
|
||||
|
||||
.linearGradient2 {
|
||||
background: -webkit-gradient(linear, 0% 0, 0% 100%, from(rgb(252, 252, 252)), to(rgb(232, 232, 232)));
|
||||
background: -webkit-gradient(linear, 0% 0, 0% 100%, from(rgb(252, 252, 252)), color-stop(0.3, #000000), to(rgb(232, 232, 232)));
|
||||
}
|
||||
|
||||
.linearGradient3 {
|
||||
|
@ -14,8 +14,14 @@
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
padding: 10px;
|
||||
border: 15px solid black;
|
||||
border: 15px solid transparent;
|
||||
}
|
||||
.linearGradient {
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
background-image: linear-gradient(rgba(0, 0, 0, 0.7) 0.1em, transparent 0.1em), linear-gradient(90deg, rgba(0, 0, 0, 0.7) 0.1em, transparent 0.1em);
|
||||
background-size: 1em 1em;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@ -38,5 +44,8 @@
|
||||
<div style="background: linear-gradient(to right, rgba(255,255,255,0) 0%,rgba(255,255,255,1) 100%); "></div>
|
||||
<div style="background: linear-gradient(90deg, yellow 0%, orange 10%, red 50%, blue 90%, cyan 100%) content-box;"></div>
|
||||
<div style="background: linear-gradient(60deg, hsla(120,80%,50%,0.8) 0%, transparent 50%, rgba(255,100,100,0.5) 100%);"></div>
|
||||
<div style="background: linear-gradient(to right, red 20%, orange 20% 40%, yellow 40% 60%, green 60% 80%, blue 80%);"></div>
|
||||
<div style="background: linear-gradient(-45deg, #FF0000 40%, #00FF00 50%);"></div>
|
||||
<div class="linearGradient"></div>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
@ -56,6 +56,6 @@
|
||||
<div style='background-size: auto 100%;'></div>
|
||||
<div style='background-size: auto;'></div>
|
||||
</div>
|
||||
|
||||
<div class="container" style="padding: 10px; background-size: contain; background-origin: content-box; background-clip: content-box"></div>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -36,7 +36,7 @@
|
||||
<input type="text" value="textbox" />
|
||||
<input type="password" value="textbox" />
|
||||
<input type="text" value="textbox" style="border:5px solid navy;" />
|
||||
<input type="text" value="textbox" style="border:5px solid navy;height:40px;" />
|
||||
<input type="text" value="textbox with very long text that overflows" style="border:5px solid navy;height:40px;" />
|
||||
|
||||
<input type="text" value="textbox" style="border:5px solid navy;height:40px;padding:10px;" />
|
||||
|
||||
|
@ -5,18 +5,9 @@
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<script type="text/javascript" src="../../test.js"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
function setUp() {
|
||||
var supportedTypes = ["decimal","decimal-leading-zero","upper-roman","lower-roman","lower-alpha","upper-alpha"];
|
||||
for (var i = 1;i<=15;i++){
|
||||
$('#dynamic').append($('<li />').text(i).css('list-style-type',supportedTypes[1]));
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
#dynamic{
|
||||
list-style-type:decimal;
|
||||
list-style-type:decimal-leading-zero;
|
||||
list-style-position: outside;
|
||||
font-size:20px;
|
||||
line-height:50px;
|
||||
@ -53,6 +44,23 @@
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<ol id="dynamic"></ol>
|
||||
|
||||
<ol id="dynamic">
|
||||
<li>1</li>
|
||||
<li>2</li>
|
||||
<li>3</li>
|
||||
<li>4</li>
|
||||
<li>5</li>
|
||||
<li>6</li>
|
||||
<li>7</li>
|
||||
<li>8</li>
|
||||
<li>9</li>
|
||||
<li>10</li>
|
||||
<li>11</li>
|
||||
<li>12</li>
|
||||
<li>13</li>
|
||||
<li>14</li>
|
||||
<li>15</li>
|
||||
</ol>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -5,15 +5,6 @@
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<script type="text/javascript" src="../../test.js"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
function setUp() {
|
||||
var supportedTypes = ["decimal","decimal-leading-zero","upper-roman","lower-roman","lower-alpha","upper-alpha"];
|
||||
for (var i = 1;i<=15;i++){
|
||||
$('#dynamic').append($('<li />').text(i).css('list-style-type',supportedTypes[0]));
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
#dynamic{
|
||||
list-style-type:decimal;
|
||||
@ -54,7 +45,23 @@
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<ol id="dynamic"></ol>
|
||||
|
||||
<ol id="dynamic">
|
||||
<li>1</li>
|
||||
<li>2</li>
|
||||
<li>3</li>
|
||||
<li>4</li>
|
||||
<li>5</li>
|
||||
<li>6</li>
|
||||
<li>7</li>
|
||||
<li>8</li>
|
||||
<li>9</li>
|
||||
<li>10</li>
|
||||
<li>11</li>
|
||||
<li>12</li>
|
||||
<li>13</li>
|
||||
<li>14</li>
|
||||
<li>15</li>
|
||||
</ol>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -1,102 +1,102 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title>List tests</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<script type="text/javascript" src="../../test.js"></script>
|
||||
<head>
|
||||
<title>List tests</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<script type="text/javascript" src="../../test.js"></script>
|
||||
|
||||
<style>
|
||||
li {
|
||||
margin: 10px 5%;
|
||||
}
|
||||
.list1 {
|
||||
list-style-type: circle;
|
||||
}
|
||||
<style>
|
||||
li {
|
||||
margin: 10px 5%;
|
||||
}
|
||||
.list1 {
|
||||
list-style-type: circle;
|
||||
}
|
||||
|
||||
.list2 {
|
||||
list-style-image: url(../../assets/image.jpg);
|
||||
}
|
||||
.list2 {
|
||||
list-style-image: url(../../assets/image.jpg);
|
||||
}
|
||||
|
||||
.list3 {
|
||||
list-style-image: linear-gradient(60deg, deeppink, aquamarine);
|
||||
list-style-position: inside;
|
||||
}
|
||||
.list3 {
|
||||
list-style-image: linear-gradient(60deg, deeppink, aquamarine);
|
||||
list-style-position: inside;
|
||||
}
|
||||
|
||||
.list4 {
|
||||
}
|
||||
.list4 {
|
||||
}
|
||||
|
||||
.list5 {
|
||||
list-style-type: lower-roman;
|
||||
}
|
||||
.list5 {
|
||||
list-style-type: lower-roman;
|
||||
}
|
||||
|
||||
.list6 {
|
||||
list-style-type: hiragana;
|
||||
}
|
||||
.list6 {
|
||||
list-style-type: hiragana;
|
||||
}
|
||||
|
||||
.list7 {
|
||||
list-style-type: simp-chinese-informal;
|
||||
}
|
||||
.list7 {
|
||||
list-style-type: simp-chinese-informal;
|
||||
}
|
||||
|
||||
.list8 {
|
||||
list-style-type: lower-roman;
|
||||
}
|
||||
.list8 {
|
||||
list-style-type: lower-roman;
|
||||
}
|
||||
|
||||
.list8 li {
|
||||
display: block;
|
||||
}
|
||||
.list8 li {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.list9 {
|
||||
display: list-item;
|
||||
list-style-type: lower-alpha;
|
||||
margin: 10px;
|
||||
position: relative;
|
||||
left: 200px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<ul class="list1">
|
||||
<li>Alpha</li>
|
||||
<li>Beta</li>
|
||||
<li>Gamma</li>
|
||||
</ul>
|
||||
<ul class="list2">
|
||||
<li>Alpha</li>
|
||||
<li>Beta</li>
|
||||
<li>Gamma</li>
|
||||
</ul>
|
||||
<ul class="list3">
|
||||
<li>Alpha</li>
|
||||
<li>Beta</li>
|
||||
<li>Gamma</li>
|
||||
</ul>
|
||||
<ol class="list4" start="-1">
|
||||
<li>Alpha</li>
|
||||
<li>Beta</li>
|
||||
<li>Gamma</li>
|
||||
</ol>
|
||||
<ol class="list5">
|
||||
<li>Alpha</li>
|
||||
<li value="5">Beta</li>
|
||||
<li>Gamma</li>
|
||||
</ol>
|
||||
<ol class="list6">
|
||||
<li>Alpha</li>
|
||||
<li>Beta</li>
|
||||
<li>Gamma</li>
|
||||
</ol>
|
||||
<ol class="list7">
|
||||
<li>Alpha</li>
|
||||
<li>Beta</li>
|
||||
<li>Gamma</li>
|
||||
</ol>
|
||||
<ol class="list8">
|
||||
<li>Alpha</li>
|
||||
<li>Beta</li>
|
||||
<li>Gamma</li>
|
||||
</ol>
|
||||
<div class="list9">Alpha</div>
|
||||
<div class="list9">Beta</div>
|
||||
<div class="list9">Gamma</div>
|
||||
</body>
|
||||
.list9 {
|
||||
display: list-item;
|
||||
list-style-type: lower-alpha;
|
||||
margin: 10px;
|
||||
position: relative;
|
||||
left: 200px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<ul class="list1">
|
||||
<li>Alpha</li>
|
||||
<li>Beta</li>
|
||||
<li>Gamma</li>
|
||||
</ul>
|
||||
<ul class="list2">
|
||||
<li>Alpha</li>
|
||||
<li>Beta</li>
|
||||
<li>Gamma</li>
|
||||
</ul>
|
||||
<ul class="list3">
|
||||
<li>Alpha</li>
|
||||
<li>Beta</li>
|
||||
<li>Gamma</li>
|
||||
</ul>
|
||||
<ol class="list4" start="-1">
|
||||
<li>Alpha</li>
|
||||
<li>Beta</li>
|
||||
<li>Gamma</li>
|
||||
</ol>
|
||||
<ol class="list5">
|
||||
<li>Alpha</li>
|
||||
<li value="5">Beta</li>
|
||||
<li>Gamma</li>
|
||||
</ol>
|
||||
<ol class="list6">
|
||||
<li>Alpha</li>
|
||||
<li>Beta</li>
|
||||
<li>Gamma</li>
|
||||
</ol>
|
||||
<ol class="list7">
|
||||
<li>Alpha</li>
|
||||
<li>Beta</li>
|
||||
<li>Gamma</li>
|
||||
</ol>
|
||||
<ol class="list8">
|
||||
<li>Alpha</li>
|
||||
<li>Beta</li>
|
||||
<li>Gamma</li>
|
||||
</ol>
|
||||
<div class="list9">list-less Alpha</div>
|
||||
<div class="list9">list-less Beta</div>
|
||||
<div class="list9">list-less Gamma</div>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -4,19 +4,9 @@
|
||||
<title>List tests</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<script type="text/javascript" src="../../test.js"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
function setUp() {
|
||||
var supportedTypes = ["decimal","decimal-leading-zero","upper-roman","lower-roman","lower-alpha","upper-alpha"];
|
||||
for (var i = 1;i<=15;i++){
|
||||
$('#dynamic').append($('<li />').text(i).css('list-style-type',supportedTypes[4]));
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
#dynamic{
|
||||
list-style-type:decimal;
|
||||
list-style-type:lower-alpha;
|
||||
list-style-position: outside;
|
||||
font-size:20px;
|
||||
line-height:50px;
|
||||
@ -54,7 +44,23 @@
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<ol id="dynamic"></ol>
|
||||
<ol id="dynamic">
|
||||
<li>1</li>
|
||||
<li>2</li>
|
||||
<li>3</li>
|
||||
<li>4</li>
|
||||
<li>5</li>
|
||||
<li>6</li>
|
||||
<li>7</li>
|
||||
<li>8</li>
|
||||
<li>9</li>
|
||||
<li>10</li>
|
||||
<li>11</li>
|
||||
<li>12</li>
|
||||
<li>13</li>
|
||||
<li>14</li>
|
||||
<li>15</li>
|
||||
</ol>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
@ -5,18 +5,9 @@
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<script type="text/javascript" src="../../test.js"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
function setUp() {
|
||||
var supportedTypes = ["decimal","decimal-leading-zero","upper-roman","lower-roman","lower-alpha","upper-alpha"];
|
||||
for (var i = 1;i<=15;i++){
|
||||
$('#dynamic').append($('<li />').text(i).css('list-style-type',supportedTypes[2]));
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
#dynamic{
|
||||
list-style-type:decimal;
|
||||
list-style-type:upper-roman;
|
||||
list-style-position: outside;
|
||||
font-size:20px;
|
||||
line-height:50px;
|
||||
@ -54,7 +45,24 @@
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<ol id="dynamic"></ol>
|
||||
|
||||
<ol id="dynamic">
|
||||
<li>1</li>
|
||||
<li>2</li>
|
||||
<li>3</li>
|
||||
<li>4</li>
|
||||
<li>5</li>
|
||||
<li>6</li>
|
||||
<li>7</li>
|
||||
<li>8</li>
|
||||
<li>9</li>
|
||||
<li>10</li>
|
||||
<li>11</li>
|
||||
<li>12</li>
|
||||
<li>13</li>
|
||||
<li>14</li>
|
||||
<li>15</li>
|
||||
</ol>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
@ -5,7 +5,7 @@
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<script>
|
||||
h2cOptions = {onclone: function(document) {
|
||||
const remove = document.querySelector('.ignored');
|
||||
var remove = document.querySelector('.ignored');
|
||||
remove.parentNode.removeChild(remove);
|
||||
}};
|
||||
</script>
|
||||
|
@ -40,6 +40,29 @@
|
||||
line-height: 17px;
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
|
||||
#app {
|
||||
background-color: lightcoral;
|
||||
width: 300px;
|
||||
color: #333;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
#box {
|
||||
background-color: lightgreen;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.content {
|
||||
background-color: lightskyblue;
|
||||
width: 150px;
|
||||
height: 150px;
|
||||
transform: translate(100px, 0);
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
</head>
|
||||
@ -51,5 +74,16 @@
|
||||
<div class="img-2"></div>
|
||||
</div>
|
||||
|
||||
|
||||
<div id="app">
|
||||
This is app
|
||||
<div id="box">
|
||||
This is box, overflow hidden
|
||||
<div class="content">
|
||||
This is content
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
@ -115,7 +115,13 @@
|
||||
|
||||
</div>
|
||||
<script>
|
||||
document.querySelector('#scroll').scrollTo(0, 200);
|
||||
try {
|
||||
document.querySelector('#scroll').scrollTo(0, 200);
|
||||
} catch(e) {
|
||||
// internet explorer
|
||||
document.querySelector('#scroll').scrollTop = 200;
|
||||
}
|
||||
|
||||
</script>
|
||||
</div>
|
||||
</body>
|
||||
|
@ -1,104 +1,167 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<script type="text/javascript" src="../test.js"></script>
|
||||
<head>
|
||||
<script type="text/javascript" src="../test.js"></script>
|
||||
|
||||
<style>
|
||||
body {
|
||||
quotes: "<{" "}>" "->" "<-" "(" ")" "-:" ":-";
|
||||
}
|
||||
<style>
|
||||
body {
|
||||
quotes: "<{" "}>" "->" "<-" "(" ")" "-:" ":-";
|
||||
}
|
||||
|
||||
.counter1,
|
||||
.counter2,
|
||||
.quotes1,
|
||||
.attr-url {
|
||||
border: 1px solid deepskyblue;
|
||||
padding: 5px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.counter1,
|
||||
.counter2,
|
||||
.quotes1,
|
||||
.attr-url {
|
||||
border: 1px solid deepskyblue;
|
||||
padding: 5px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.counter1 {
|
||||
counter-reset: c1 3;
|
||||
}
|
||||
.counter1 {
|
||||
counter-reset: c1 3;
|
||||
}
|
||||
|
||||
.counter1 > div::before {
|
||||
content: "«\"" counter(c1) "\»";
|
||||
counter-increment: c1 -1;
|
||||
}
|
||||
.counter1 > div::before {
|
||||
content: "«\"" counter(c1) "\»";
|
||||
counter-increment: c1 -1;
|
||||
}
|
||||
|
||||
.counter2 {
|
||||
counter-reset: c2;
|
||||
}
|
||||
.counter2 {
|
||||
counter-reset: c2;
|
||||
}
|
||||
|
||||
.counter2 > div::before {
|
||||
content: "["counters(c2, " < ", upper-roman) ']';
|
||||
counter-increment: c2 2;
|
||||
}
|
||||
.counter2 > div::before {
|
||||
content: "["counters(c2, " < ", upper-roman) ']';
|
||||
counter-increment: c2 2;
|
||||
}
|
||||
|
||||
.quotes1::before {
|
||||
content: open-quote "!" open-quote close-quote open-quote;
|
||||
}
|
||||
.counter-divs {
|
||||
counter-reset: c5 3;
|
||||
}
|
||||
|
||||
.quotes1::after {
|
||||
content: "!" close-quote close-quote;
|
||||
}
|
||||
.counter-divs div {
|
||||
counter-increment: c5 1;
|
||||
}
|
||||
|
||||
.quotes2 {
|
||||
quotes: "«" "»" "“" "”";
|
||||
}
|
||||
.counter-divs > div::before {
|
||||
content: "["counter(c5) ']';
|
||||
counter-increment: c5 2;
|
||||
}
|
||||
|
||||
.quotes2::before {
|
||||
content: open-quote;
|
||||
}
|
||||
.quotes1::before {
|
||||
content: open-quote "!" open-quote close-quote open-quote;
|
||||
}
|
||||
|
||||
.quotes2::after {
|
||||
content: close-quote;
|
||||
}
|
||||
.quotes1::after {
|
||||
content: "!" close-quote close-quote;
|
||||
}
|
||||
|
||||
.attr-url > div::after {
|
||||
content: url(../assets/image.jpg) "///" attr(data-text);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="counter1">
|
||||
<div>A</div>
|
||||
<div>B</div>
|
||||
<div>C</div>
|
||||
<div>D</div>
|
||||
</div>
|
||||
.quotes2 {
|
||||
quotes: "«" "»" "“" "”";
|
||||
}
|
||||
|
||||
<div class="counter2">
|
||||
<div>A</div>
|
||||
<div>B</div>
|
||||
<div>
|
||||
C
|
||||
<div class="counter2">
|
||||
<div>a</div>
|
||||
<div>b</div>
|
||||
<div>
|
||||
c
|
||||
<div class="counter2">
|
||||
<div>Aa</div>
|
||||
<div>Bb</div>
|
||||
<div>Cc</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>D</div>
|
||||
</div>
|
||||
.quotes2::before {
|
||||
content: open-quote;
|
||||
}
|
||||
|
||||
<div class="quotes1">
|
||||
Hello
|
||||
<div class="quotes2">
|
||||
Quoted
|
||||
<div class="quotes2">World</div>
|
||||
</div>
|
||||
</div>
|
||||
.quotes2::after {
|
||||
content: close-quote close-quote close-quote close-quote;
|
||||
}
|
||||
|
||||
<div class="attr-url">
|
||||
<div data-text="Hello World"></div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
.attr-url > div::after {
|
||||
content: url(../assets/image.jpg) "///" attr(data-text);
|
||||
}
|
||||
|
||||
ol {
|
||||
counter-reset: section; /* Creates a new instance of the
|
||||
section counter with each ol
|
||||
element */
|
||||
list-style-type: none;
|
||||
}
|
||||
|
||||
li::before {
|
||||
counter-increment: section; /* Increments only this instance
|
||||
of the section counter */
|
||||
content: counters(section, ".") " "; /* Combines the values of all instances
|
||||
of the section counter, separated
|
||||
by a period */
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="counter1">
|
||||
<div>A</div>
|
||||
<div>B</div>
|
||||
<div>C</div>
|
||||
<div>D</div>
|
||||
</div>
|
||||
|
||||
<div class="counter2">
|
||||
<div>A</div>
|
||||
<div>B</div>
|
||||
<div>
|
||||
C
|
||||
<div class="counter2">
|
||||
<div>a</div>
|
||||
<div>b</div>
|
||||
<div>
|
||||
c
|
||||
<div class="counter2">
|
||||
<div>Aa</div>
|
||||
<div>Bb</div>
|
||||
<div>Cc</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>D</div>
|
||||
</div>
|
||||
|
||||
<div class="quotes1">
|
||||
Hello
|
||||
<div class="quotes2">
|
||||
Quoted
|
||||
<div class="quotes2">World</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="attr-url">
|
||||
<div data-text="Hello World"></div>
|
||||
</div>
|
||||
|
||||
<div class="counter-divs">
|
||||
<div>A</div>
|
||||
<div>B</div>
|
||||
<div>C</div>
|
||||
<div>D</div>
|
||||
</div>
|
||||
<ol>
|
||||
<li>item</li> <!-- 1 -->
|
||||
<li>item <!-- 2 -->
|
||||
<ol>
|
||||
<li>item</li> <!-- 2.1 -->
|
||||
<li>item</li> <!-- 2.2 -->
|
||||
<li>item <!-- 2.3 -->
|
||||
<ol>
|
||||
<li>item</li> <!-- 2.3.1 -->
|
||||
<li>item</li> <!-- 2.3.2 -->
|
||||
</ol>
|
||||
<ol>
|
||||
<li>item</li> <!-- 2.3.1 -->
|
||||
<li>item</li> <!-- 2.3.2 -->
|
||||
<li>item</li> <!-- 2.3.3 -->
|
||||
</ol>
|
||||
</li>
|
||||
<li>item</li> <!-- 2.4 -->
|
||||
</ol>
|
||||
</li>
|
||||
<li>item</li> <!-- 3 -->
|
||||
<li>item</li> <!-- 4 -->
|
||||
</ol>
|
||||
<ol>
|
||||
<li>item</li> <!-- 1 -->
|
||||
<li>item</li> <!-- 2 -->
|
||||
</ol>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
@ -12,7 +12,7 @@
|
||||
background-color: green;
|
||||
}
|
||||
body {
|
||||
font-family: Arial;
|
||||
font-family: "Helvetica Neue", Arial, sans-serif;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
<script type="text/javascript">
|
||||
function setUp() {
|
||||
$('body').empty();
|
||||
$.each(['arial','verdana','tahoma','courier new'],function(i,e){
|
||||
$.each(['arial','verdana','courier new'],function(i,e){
|
||||
var div = $('<div />').css('font-family',e).appendTo('body');
|
||||
for(var i=0;i<=5;i++){
|
||||
$('<div />').text('Testing texts').css('margin-top',1).css('border','1px solid black').css('font-size',(16+i*6)).appendTo(div);
|
||||
|
@ -7,7 +7,7 @@
|
||||
<script type="text/javascript">
|
||||
function setUp() {
|
||||
$('body').empty();
|
||||
$.each(['arial','verdana','tahoma','courier new'],function(i,e){
|
||||
$.each(['arial','verdana','courier new'],function(i,e){
|
||||
var div = $('<div />').css('font-family',e).appendTo('body');
|
||||
for(var i=0;i<=5;i++){
|
||||
$('<div />').text('Testing texts').css('margin-top',1).css('border','1px solid black').css('font-size',(16+i*6)).appendTo(div);
|
||||
|
@ -6,13 +6,20 @@
|
||||
<script type="text/javascript" src="../../test.js"></script>
|
||||
<script type="text/javascript">
|
||||
function setUp() {
|
||||
$('body').empty();
|
||||
$.each(['arial','verdana','tahoma','courier new'],function(i,e){
|
||||
var div = $('<div />').css('font-family',e).appendTo('body');
|
||||
for(var i=1;i<=10;i*=2){
|
||||
$('<div />').text('Testing texts').css('margin-top',1).css('font-size',(16+i*6)).appendTo(div);
|
||||
}
|
||||
var container = document.querySelector('#test');
|
||||
container.innerHTML = '';
|
||||
|
||||
['arial','verdana','courier new'].forEach(function(e) {
|
||||
var div = document.createElement('div');
|
||||
div.style.fontFamily = e;
|
||||
container.appendChild(div);
|
||||
for(var i=1;i<=10;i*=2) {
|
||||
var text = document.createElement('div');
|
||||
text.innerText = 'Testing texts';
|
||||
text.style.marginTop = '1px';
|
||||
text.style.fontSize = (16+i*6) + 'px';
|
||||
div.appendChild(text);
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
@ -45,6 +52,9 @@
|
||||
|
||||
</head>
|
||||
<body>
|
||||
Creating content through JavaScript
|
||||
test <u> </u> label u
|
||||
<div id="test">
|
||||
Creating content through JavaScript
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
52
tests/rollup.config.ts
Normal file
52
tests/rollup.config.ts
Normal file
@ -0,0 +1,52 @@
|
||||
import nodeResolve from 'rollup-plugin-node-resolve';
|
||||
import commonjs from 'rollup-plugin-commonjs';
|
||||
import sourceMaps from 'rollup-plugin-sourcemaps';
|
||||
import typescript from 'rollup-plugin-typescript2';
|
||||
import json from 'rollup-plugin-json';
|
||||
import {resolve} from 'path';
|
||||
|
||||
const pkg = require('../package.json');
|
||||
|
||||
const banner = `/*
|
||||
* ${pkg.title} ${pkg.version} <${pkg.homepage}>
|
||||
* Copyright (c) ${new Date().getFullYear()} ${pkg.author.name} <${pkg.author.url}>
|
||||
* Released under ${pkg.license} License
|
||||
*/`;
|
||||
|
||||
export default {
|
||||
input: `tests/testrunner.ts`,
|
||||
output: [
|
||||
{
|
||||
file: resolve(__dirname, '../build/testrunner.js'),
|
||||
name: 'testrunner',
|
||||
format: 'iife',
|
||||
banner,
|
||||
sourcemap: true
|
||||
}
|
||||
],
|
||||
external: [],
|
||||
watch: {
|
||||
include: 'tests/**'
|
||||
},
|
||||
plugins: [
|
||||
// Allow node_modules resolution, so you can use 'external' to control
|
||||
// which external modules to include in the bundle
|
||||
// https://github.com/rollup/rollup-plugin-node-resolve#usage
|
||||
nodeResolve(),
|
||||
// Allow json resolution
|
||||
json(),
|
||||
// Compile TypeScript files
|
||||
typescript({useTsconfigDeclarationDir: true}),
|
||||
// Allow bundling cjs modules (unlike webpack, rollup doesn't understand cjs)
|
||||
commonjs({
|
||||
include: 'node_modules/**',
|
||||
namedModules: {
|
||||
'node_modules/platform/platform.js': ['name', 'version'],
|
||||
'node_modules/es6-promise/dist/es6-promise.js': ['Promise']
|
||||
}
|
||||
}),
|
||||
|
||||
// Resolve source maps to the original source
|
||||
sourceMaps()
|
||||
]
|
||||
};
|
@ -2,8 +2,6 @@ const express = require('express');
|
||||
const cors = require('cors');
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
const webpack = require('webpack');
|
||||
const config = require('../webpack.config');
|
||||
const serveIndex = require('serve-index');
|
||||
const proxy = require('html2canvas-proxy');
|
||||
|
||||
@ -24,20 +22,3 @@ corsApp.use('/', express.static(path.resolve(__dirname, '.')));
|
||||
corsApp.listen(CORS_PORT, () => {
|
||||
console.log(`CORS server running on port ${CORS_PORT}`);
|
||||
});
|
||||
|
||||
const compiler = webpack(config);
|
||||
compiler.watch(
|
||||
{
|
||||
aggregateTimeout: 300 // wait so long for more changes
|
||||
},
|
||||
(err, stats) => {
|
||||
console.error(err);
|
||||
|
||||
console.log(
|
||||
stats.toString({
|
||||
chunks: false, // Makes the build much quieter
|
||||
colors: true
|
||||
})
|
||||
);
|
||||
}
|
||||
);
|
||||
|
@ -17,7 +17,7 @@ var REFTEST = window.location.search.indexOf('reftest') !== -1;
|
||||
);
|
||||
}
|
||||
|
||||
(typeof Promise === 'undefined' ? ['/node_modules/promise-polyfill/promise.min'] : [])
|
||||
(typeof Promise === 'undefined' ? ['/node_modules/es6-promise/dist/es6-promise.auto.min'] : [])
|
||||
.concat([
|
||||
'/node_modules/jquery/dist/jquery.min',
|
||||
'/dist/html2canvas'
|
||||
@ -25,9 +25,6 @@ var REFTEST = window.location.search.indexOf('reftest') !== -1;
|
||||
.forEach(appendScript);
|
||||
|
||||
window.onload = function() {
|
||||
var targets = REFTEST
|
||||
? [new html2canvas.CanvasRenderer(), new RefTestRenderer()]
|
||||
: new html2canvas.CanvasRenderer();
|
||||
(function($) {
|
||||
$.fn.html2canvas = function(options) {
|
||||
var date = new Date(),
|
||||
@ -40,18 +37,7 @@ var REFTEST = window.location.search.indexOf('reftest') !== -1;
|
||||
console.log('html2canvas threw an error', err);
|
||||
});
|
||||
|
||||
promise.then(function(output) {
|
||||
var canvas = Array.isArray(targets) ? output[0] : output;
|
||||
if (Array.isArray(targets)) {
|
||||
console.log(
|
||||
output[1]
|
||||
.split('\n')
|
||||
.map(function(line, i) {
|
||||
return i + 1 + ':' + line;
|
||||
})
|
||||
.join('\n')
|
||||
);
|
||||
}
|
||||
promise.then(function(canvas) {
|
||||
var $canvas = $(canvas),
|
||||
finishTime = new Date();
|
||||
|
||||
@ -155,8 +141,7 @@ var REFTEST = window.location.search.indexOf('reftest') !== -1;
|
||||
logging: true,
|
||||
proxy: 'http://localhost:8081/proxy',
|
||||
useCORS: false,
|
||||
removeContainer: false,
|
||||
target: targets
|
||||
removeContainer: true
|
||||
},
|
||||
h2cOptions,
|
||||
REFTEST ? {windowWidth: 800, windowHeight: 600} : {}
|
||||
|
@ -1,385 +0,0 @@
|
||||
import {expect} from 'chai';
|
||||
import parseRefTest from '../scripts/parse-reftest';
|
||||
import reftests from './reftests';
|
||||
import querystring from 'querystring';
|
||||
import platform from 'platform';
|
||||
import Promise from 'promise-polyfill';
|
||||
|
||||
const DOWNLOAD_REFTESTS = false;
|
||||
const query = querystring.parse(location.search.replace(/^\?/, ''));
|
||||
|
||||
const downloadResult = (filename, data) => {
|
||||
const downloadUrl = URL.createObjectURL(new Blob([data], {type: 'text/plain'}));
|
||||
const a = document.createElement('a');
|
||||
a.href = downloadUrl;
|
||||
a.download = filename;
|
||||
|
||||
setTimeout(() => {
|
||||
a.click();
|
||||
URL.revokeObjectURL(downloadUrl);
|
||||
document.body.removeChild(a);
|
||||
}, 100);
|
||||
|
||||
document.body.appendChild(a);
|
||||
};
|
||||
|
||||
const assertPath = (result, expected, desc) => {
|
||||
expect(result.length).to.equal(expected.length, `${desc} path length`);
|
||||
|
||||
expected.forEach((e, i) => {
|
||||
const r = result[i];
|
||||
expect(r.type).to.equal(e.type, `${desc} type`);
|
||||
if (Array.isArray(r)) {
|
||||
assertPath(r, e, desc);
|
||||
} else {
|
||||
switch (r.type) {
|
||||
case 'Circle':
|
||||
expect(r.x).to.be.closeTo(e.x, 10, `${desc} Circle #${i + 1} x`);
|
||||
expect(r.y).to.be.closeTo(e.y, 10, `${desc} Circle #${i + 1} y`);
|
||||
expect(r.r).to.be.closeTo(e.r, 5, `${desc} Circle #${i + 1} r`);
|
||||
break;
|
||||
case 'Vector':
|
||||
expect(r.x).to.be.closeTo(e.x, 10, `${desc} vector #${i + 1} x`);
|
||||
expect(r.y).to.be.closeTo(e.y, 10, `${desc} vector #${i + 1} y`);
|
||||
break;
|
||||
case 'BezierCurve':
|
||||
expect(r.x0).to.be.closeTo(e.x0, 10, `${desc} beziercurve #${i + 1} x0`);
|
||||
expect(r.y0).to.be.closeTo(e.y0, 10, `${desc} beziercurve #${i + 1} y0`);
|
||||
expect(r.x1).to.be.closeTo(e.x1, 10, `${desc} beziercurve #${i + 1} x1`);
|
||||
expect(r.y1).to.be.closeTo(e.y1, 10, `${desc} beziercurve #${i + 1} y1`);
|
||||
expect(r.cx0).to.be.closeTo(e.cx0, 10, `${desc} beziercurve #${i + 1} cx0`);
|
||||
expect(r.cy0).to.be.closeTo(e.cy0, 10, `${desc} beziercurve #${i + 1} cy0`);
|
||||
expect(r.cx1).to.be.closeTo(e.cx1, 10, `${desc} beziercurve #${i + 1} cx1`);
|
||||
expect(r.cy1).to.be.closeTo(e.cy1, 10, `${desc} beziercurve #${i + 1} cy1`);
|
||||
break;
|
||||
default:
|
||||
throw new Error(`Unknown path type ${r.type}`);
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
(() => {
|
||||
const testRunnerUrl = location.href;
|
||||
const hasHistoryApi =
|
||||
typeof window.history !== 'undefined' && typeof window.history.replaceState !== 'undefined';
|
||||
|
||||
if (typeof reftests === 'undefined') {
|
||||
it('Test harness prerequisite check', () => {
|
||||
throw new Error(
|
||||
'No reftests list defined, run "npm run create-reftest-list" to create it'
|
||||
);
|
||||
});
|
||||
} else {
|
||||
Object.keys(reftests.testList)
|
||||
.filter(test => {
|
||||
return (
|
||||
!Array.isArray(reftests.ignoredTests[test]) ||
|
||||
reftests.ignoredTests[test].indexOf(platform.name) === -1
|
||||
);
|
||||
})
|
||||
.forEach(url => {
|
||||
describe(url, function() {
|
||||
this.timeout(60000);
|
||||
this.retries(2);
|
||||
const windowWidth = 800;
|
||||
const windowHeight = 600;
|
||||
const testContainer = document.createElement('iframe');
|
||||
const REFTEST = reftests.testList[url];
|
||||
testContainer.width = windowWidth;
|
||||
testContainer.height = windowHeight;
|
||||
testContainer.style.visibility = 'hidden';
|
||||
testContainer.style.position = 'fixed';
|
||||
testContainer.style.left = '10000px';
|
||||
|
||||
before(done => {
|
||||
testContainer.onload = () => done();
|
||||
|
||||
testContainer.src = url + '?selenium&run=false&reftest&' + Math.random();
|
||||
if (hasHistoryApi) {
|
||||
// Chrome does not resolve relative background urls correctly inside of a nested iframe
|
||||
try {
|
||||
history.replaceState(null, '', url);
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
document.body.appendChild(testContainer);
|
||||
});
|
||||
after(() => {
|
||||
if (hasHistoryApi) {
|
||||
try {
|
||||
history.replaceState(null, '', testRunnerUrl);
|
||||
} catch (e) {}
|
||||
}
|
||||
document.body.removeChild(testContainer);
|
||||
});
|
||||
it('Should render untainted canvas', () => {
|
||||
return testContainer.contentWindow
|
||||
.html2canvas(
|
||||
testContainer.contentWindow.forceElement ||
|
||||
testContainer.contentWindow.document.documentElement,
|
||||
{
|
||||
removeContainer: true,
|
||||
backgroundColor: '#ffffff',
|
||||
proxy: 'http://localhost:8081/proxy',
|
||||
...(testContainer.contentWindow.h2cOptions || {})
|
||||
}
|
||||
)
|
||||
.then(canvas => {
|
||||
try {
|
||||
canvas
|
||||
.getContext('2d')
|
||||
.getImageData(0, 0, canvas.width, canvas.height);
|
||||
} catch (e) {
|
||||
return Promise.reject('Canvas is tainted');
|
||||
}
|
||||
|
||||
const delta = 10;
|
||||
|
||||
if (REFTEST && query.refTest === 'true') {
|
||||
const RESULTS = parseRefTest(result);
|
||||
REFTEST.forEach(({action, line, ...args}, i) => {
|
||||
const RESULT = RESULTS[i];
|
||||
expect(RESULT.action).to.equal(action, `Line ${line}`);
|
||||
|
||||
const desc = `Line ${line} ${action}`;
|
||||
|
||||
switch (action) {
|
||||
case 'Window':
|
||||
expect(RESULT.width).to.equal(
|
||||
args.width,
|
||||
`${desc} width`
|
||||
);
|
||||
expect(RESULT.height).to.be.closeTo(
|
||||
args.height,
|
||||
delta,
|
||||
`${desc} height`
|
||||
);
|
||||
break;
|
||||
|
||||
case 'Rectangle':
|
||||
expect(RESULT.x).to.equal(args.x, `${desc} x`);
|
||||
expect(RESULT.y).to.equal(args.y, `${desc} y`);
|
||||
expect(RESULT.width).to.equal(
|
||||
args.width,
|
||||
`${desc} width`
|
||||
);
|
||||
expect(RESULT.height).to.be.closeTo(
|
||||
args.height,
|
||||
delta,
|
||||
`${desc} height`
|
||||
);
|
||||
break;
|
||||
|
||||
case 'Fill':
|
||||
expect(RESULT.color).to.equal(
|
||||
args.color,
|
||||
`${desc} color`
|
||||
);
|
||||
break;
|
||||
|
||||
case 'Opacity':
|
||||
expect(RESULT.opacity).to.equal(
|
||||
args.opacity,
|
||||
`${desc} opacity`
|
||||
);
|
||||
break;
|
||||
|
||||
case 'Text':
|
||||
expect(RESULT.font).to.equal(
|
||||
args.font,
|
||||
`${desc} font`
|
||||
);
|
||||
break;
|
||||
|
||||
case 'T':
|
||||
expect(RESULT.x).to.be.closeTo(
|
||||
args.x,
|
||||
10,
|
||||
`${desc} x`
|
||||
);
|
||||
expect(RESULT.y).to.be.closeTo(
|
||||
args.y,
|
||||
10,
|
||||
`${desc} y`
|
||||
);
|
||||
expect(RESULT.text).to.equal(
|
||||
args.text,
|
||||
`${desc} text`
|
||||
);
|
||||
break;
|
||||
|
||||
case 'Transform':
|
||||
expect(RESULT.x).to.be.closeTo(
|
||||
args.x,
|
||||
10,
|
||||
`${desc} x`
|
||||
);
|
||||
expect(RESULT.y).to.be.closeTo(
|
||||
args.y,
|
||||
10,
|
||||
`${desc} y`
|
||||
);
|
||||
expect(RESULT.matrix).to.equal(
|
||||
args.matrix,
|
||||
`${desc} matrix`
|
||||
);
|
||||
break;
|
||||
|
||||
case 'Repeat':
|
||||
expect(RESULT.x).to.be.closeTo(
|
||||
args.x,
|
||||
10,
|
||||
`${desc} x`
|
||||
);
|
||||
expect(RESULT.y).to.be.closeTo(
|
||||
args.y,
|
||||
10,
|
||||
`${desc} y`
|
||||
);
|
||||
expect(RESULT.width).to.be.closeTo(
|
||||
args.width,
|
||||
3,
|
||||
`${desc} width`
|
||||
);
|
||||
expect(RESULT.height).to.be.closeTo(
|
||||
args.height,
|
||||
3,
|
||||
`${desc} height`
|
||||
);
|
||||
expect(RESULT.imageSrc).to.equal(
|
||||
args.imageSrc,
|
||||
`${desc} imageSrc`
|
||||
);
|
||||
assertPath(RESULT.path, args.path, desc);
|
||||
break;
|
||||
|
||||
case 'Gradient':
|
||||
expect(RESULT.x).to.be.closeTo(
|
||||
args.x,
|
||||
10,
|
||||
`${desc} x`
|
||||
);
|
||||
expect(RESULT.y).to.be.closeTo(
|
||||
args.y,
|
||||
10,
|
||||
`${desc} y`
|
||||
);
|
||||
expect(RESULT.x0).to.be.closeTo(
|
||||
args.x0,
|
||||
5,
|
||||
`${desc} x0`
|
||||
);
|
||||
expect(RESULT.y0).to.be.closeTo(
|
||||
args.y0,
|
||||
5,
|
||||
`${desc} y0`
|
||||
);
|
||||
expect(RESULT.x1).to.be.closeTo(
|
||||
args.x1,
|
||||
5,
|
||||
`${desc} x1`
|
||||
);
|
||||
expect(RESULT.y1).to.be.closeTo(
|
||||
args.y1,
|
||||
5,
|
||||
`${desc} y1`
|
||||
);
|
||||
expect(RESULT.stops).to.equal(
|
||||
args.stops,
|
||||
`${desc} stops`
|
||||
);
|
||||
expect(RESULT.width).to.equal(
|
||||
args.width,
|
||||
`${desc} width`
|
||||
);
|
||||
expect(RESULT.height).to.equal(
|
||||
args.height,
|
||||
`${desc} height`
|
||||
);
|
||||
|
||||
break;
|
||||
|
||||
case 'Draw image':
|
||||
expect(RESULT.imageSrc).to.equal(
|
||||
args.imageSrc,
|
||||
`${desc} stops`
|
||||
);
|
||||
expect(RESULT.sx).to.equal(args.sx, `${desc} sx`);
|
||||
expect(RESULT.sy).to.equal(args.sy, `${desc} sy`);
|
||||
expect(RESULT.dx).to.equal(args.dx, `${desc} dx`);
|
||||
expect(RESULT.dy).to.equal(args.dy, `${desc} dy`);
|
||||
expect(RESULT.sw).to.equal(args.sw, `${desc} sw`);
|
||||
expect(RESULT.sh).to.equal(args.sh, `${desc} sh`);
|
||||
expect(RESULT.dw).to.equal(args.dw, `${desc} dw`);
|
||||
expect(RESULT.dh).to.equal(args.dh, `${desc} dh`);
|
||||
break;
|
||||
|
||||
case 'Clip':
|
||||
assertPath(RESULT.path, args.path, desc);
|
||||
break;
|
||||
|
||||
case 'Shape':
|
||||
expect(RESULT.color).to.equal(
|
||||
args.color,
|
||||
`${desc} color`
|
||||
);
|
||||
assertPath(RESULT.path, args.path, desc);
|
||||
break;
|
||||
|
||||
default:
|
||||
console.log(RESULT);
|
||||
throw new Error(`Unrecognized action ${action}`);
|
||||
}
|
||||
});
|
||||
} else if (DOWNLOAD_REFTESTS) {
|
||||
downloadResult(
|
||||
url
|
||||
.slice(url.lastIndexOf('/') + 1)
|
||||
.replace(/\.html$/i, '.txt'),
|
||||
result
|
||||
);
|
||||
}
|
||||
|
||||
if (window.__karma__) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const xhr =
|
||||
'withCredentials' in new XMLHttpRequest()
|
||||
? new XMLHttpRequest()
|
||||
: new XDomainRequest();
|
||||
|
||||
xhr.onload = () => {
|
||||
if (
|
||||
typeof xhr.status !== 'number' ||
|
||||
xhr.status === 200
|
||||
) {
|
||||
resolve();
|
||||
} else {
|
||||
reject(
|
||||
`Failed to send screenshot with status ${xhr.status}`
|
||||
);
|
||||
}
|
||||
};
|
||||
xhr.onerror = reject;
|
||||
|
||||
xhr.open('POST', 'http://localhost:8000/screenshot', true);
|
||||
xhr.send(JSON.stringify({
|
||||
screenshot: canvas.toDataURL(),
|
||||
test: url,
|
||||
platform: {
|
||||
name: platform.name,
|
||||
version: platform.version
|
||||
},
|
||||
devicePixelRatio: window.devicePixelRatio || 1,
|
||||
windowWidth: window.innerWidth,
|
||||
windowHeight: window.innerHeight
|
||||
}));
|
||||
});
|
||||
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
})();
|
115
tests/testrunner.ts
Normal file
115
tests/testrunner.ts
Normal file
@ -0,0 +1,115 @@
|
||||
import {testList, ignoredTests} from '../build/reftests';
|
||||
// @ts-ignore
|
||||
import {default as platform} from 'platform';
|
||||
// @ts-ignore
|
||||
import Promise from 'es6-promise';
|
||||
|
||||
const testRunnerUrl = location.href;
|
||||
const hasHistoryApi = typeof window.history !== 'undefined' && typeof window.history.replaceState !== 'undefined';
|
||||
|
||||
const uploadResults = (canvas: HTMLCanvasElement, url: string) => {
|
||||
return new Promise((resolve: () => void, reject: (error: string) => void) => {
|
||||
// @ts-ignore
|
||||
const xhr = 'withCredentials' in new XMLHttpRequest() ? new XMLHttpRequest() : new XDomainRequest();
|
||||
|
||||
xhr.onload = () => {
|
||||
if (typeof xhr.status !== 'number' || xhr.status === 200) {
|
||||
resolve();
|
||||
} else {
|
||||
reject(`Failed to send screenshot with status ${xhr.status}`);
|
||||
}
|
||||
};
|
||||
xhr.onerror = reject;
|
||||
|
||||
xhr.open('POST', 'http://localhost:8000/screenshot', true);
|
||||
xhr.send(
|
||||
JSON.stringify({
|
||||
screenshot: canvas.toDataURL(),
|
||||
test: url,
|
||||
platform: {
|
||||
name: platform.name,
|
||||
version: platform.version
|
||||
},
|
||||
devicePixelRatio: window.devicePixelRatio || 1,
|
||||
windowWidth: window.innerWidth,
|
||||
windowHeight: window.innerHeight
|
||||
})
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
testList
|
||||
.filter(test => {
|
||||
return !Array.isArray(ignoredTests[test]) || ignoredTests[test].indexOf(platform.name || '') === -1;
|
||||
})
|
||||
.forEach(url => {
|
||||
describe(url, function() {
|
||||
this.timeout(60000);
|
||||
this.retries(2);
|
||||
const windowWidth = 800;
|
||||
const windowHeight = 600;
|
||||
const testContainer = document.createElement('iframe');
|
||||
testContainer.width = windowWidth.toString();
|
||||
testContainer.height = windowHeight.toString();
|
||||
testContainer.style.visibility = 'hidden';
|
||||
testContainer.style.position = 'fixed';
|
||||
testContainer.style.left = '10000px';
|
||||
|
||||
before(done => {
|
||||
testContainer.onload = () => done();
|
||||
|
||||
testContainer.src = url + '?selenium&run=false&reftest&' + Math.random();
|
||||
if (hasHistoryApi) {
|
||||
// Chrome does not resolve relative background urls correctly inside of a nested iframe
|
||||
try {
|
||||
history.replaceState(null, '', url);
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
document.body.appendChild(testContainer);
|
||||
});
|
||||
after(() => {
|
||||
if (hasHistoryApi) {
|
||||
try {
|
||||
history.replaceState(null, '', testRunnerUrl);
|
||||
} catch (e) {}
|
||||
}
|
||||
document.body.removeChild(testContainer);
|
||||
});
|
||||
it('Should render untainted canvas', () => {
|
||||
const contentWindow = testContainer.contentWindow;
|
||||
if (!contentWindow) {
|
||||
throw new Error('Window not found for iframe');
|
||||
}
|
||||
|
||||
return (
|
||||
contentWindow
|
||||
// @ts-ignore
|
||||
.html2canvas(contentWindow.forceElement || contentWindow.document.documentElement, {
|
||||
removeContainer: true,
|
||||
backgroundColor: '#ffffff',
|
||||
proxy: 'http://localhost:8081/proxy',
|
||||
// @ts-ignore
|
||||
...(contentWindow.h2cOptions || {})
|
||||
})
|
||||
.then((canvas: HTMLCanvasElement) => {
|
||||
try {
|
||||
(canvas.getContext('2d') as CanvasRenderingContext2D).getImageData(
|
||||
0,
|
||||
0,
|
||||
canvas.width,
|
||||
canvas.height
|
||||
);
|
||||
} catch (e) {
|
||||
return Promise.reject('Canvas is tainted');
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
if (window.__karma__) {
|
||||
return uploadResults(canvas, url);
|
||||
}
|
||||
})
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
Reference in New Issue
Block a user