Commit 9697410d 9697410dde3e5797591ee0593fed82d2b46cf370 by Nicolas Perriault

closes #150 - added Casper.captureBase64()

1 parent 86b650c0
......@@ -17,6 +17,7 @@ XXXX-XX-XX, v1.0
- added [`Casper.userAgent()`](http://casperjs.org/api.html#casper.userAgent) to ease a more dynamic setting of user-agent string
- added [`Tester.assertTitleMatch()`](http://casperjs.org/api.html#tester.assertTitleMatch) method
- added [`utils.getPropertyPath()`](http://casperjs.org/api.html#utils.getPropertyPath)
- added [`Casper.captureBase64()`](http://casperjs.org/api.html#casper.captureBase64) for rendering screen captures as base64 strings - closes [#150](https://github.com/n1k0/casperjs/issues/150)
- added [`Casper.reload()`](http://casperjs.org/api.html#casper.reload)
- added experimental support of custom headers sending in outgoing request (refs [#137](https://github.com/n1k0/casperjs/issues/137) - PhantomJS 1.6 required)
- switched to more standard `.textContent` property to get a node text; this allows a better compatibility of the clientutils bookmarklet with non-webkit browsers
......
......@@ -246,7 +246,47 @@ Casper.prototype.capture = function capture(targetFile, clipRect) {
};
/**
* Captures the page area containing the provided selector.
* Returns a Base64 representation of a binary image capture of the current
* page, or an area within the page, in a given format.
*
* Supported image formats are `bmp`, `jpg`, `jpeg`, `png`, `ppm`, `tiff`,
* `xbm` and `xpm`.
*
* @param String format The image format
* @param String|Object|undefined selector CSS3 selector or clipRect object (optional)
* @return Casper
*/
Casper.prototype.captureBase64 = function captureBase64(format, area) {
"use strict";
var base64;
var previousClipRect;
var formats = ['bmp', 'jpg', 'jpeg', 'png', 'ppm', 'tiff', 'xbm', 'xpm'];
if (formats.indexOf(format.toLowerCase()) === -1) {
throw new CasperError(f('Unsupported format "%s"', format));
}
if (utils.isClipRect(area)) {
// if area is a clipRect object
this.log(f("Capturing base64 %s representation of %s", format, utils.serialize(area)), "debug");
previousClipRect = this.page.clipRect;
this.page.clipRect = area;
base64 = this.page.renderBase64(format);
} else if (utils.isValidSelector(area)) {
// if area is a selector string or object
this.log(f("Capturing base64 %s representation of %s", format, area), "debug");
base64 = this.captureBase64(format, this.getElementBounds(area));
} else {
// whole page capture
this.log(f("Capturing base64 %s representation of page", format), "debug");
base64 = this.page.renderBase64(format);
}
if (previousClipRect) {
this.page.clipRect = previousClipRect;
}
return base64;
};
/**
* Captures the page area matching the provided selector.
*
* @param String targetFile Target destination file path.
* @param String selector CSS3 selector
......
......@@ -57,7 +57,7 @@
* @param Mixed value
*/
function dump(value) {
console.log(serialize(value));
console.log(serialize(value, 4));
}
exports.dump = dump;
......@@ -304,6 +304,39 @@
exports.isUndefined = isUndefined;
/**
* Checks if value is a valid selector Object.
*
* @param mixed value
* @return Boolean
*/
function isValidSelector(value) {
if (isString(value)) {
try {
// phantomjs env has a working document object, let's use it
document.querySelector(value);
} catch(e) {
if ('name' in e && e.name === 'SYNTAX_ERR') {
return false;
}
}
return true;
} else if (isObject(value)) {
if (!value.hasOwnProperty('type')) {
return false;
}
if (!value.hasOwnProperty('path')) {
return false;
}
if (['css', 'xpath'].indexOf(value.type) === -1) {
return false;
}
return true;
}
return false;
}
exports.isValidSelector = isValidSelector;
/**
* Checks if the provided var is a WebPage instance
*
* @param mixed what
......@@ -362,13 +395,13 @@
* @param Mixed value
* @return String
*/
function serialize(value) {
function serialize(value, indent) {
if (isArray(value)) {
value = value.map(function _map(prop) {
return isFunction(prop) ? prop.toString().replace(/\s{2,}/, '') : prop;
});
}
return JSON.stringify(value, null, 4);
return JSON.stringify(value, null, indent);
}
exports.serialize = serialize;
......
......@@ -4,17 +4,26 @@ if (fs.exists(testFile) && fs.isFile(testFile)) {
fs.remove(testFile);
}
casper.start('tests/site/index.html', function(self) {
self.viewport(300, 200);
casper.start('tests/site/index.html', function() {
this.viewport(300, 200);
this.test.comment('Casper.capture()');
self.capture(testFile);
this.capture(testFile);
this.test.assert(fs.isFile(testFile), 'Casper.capture() captured a screenshot');
});
try {
fs.remove(testFile);
} catch(e) {}
casper.thenOpen('tests/site/index.html', function() {
this.test.comment('Casper.captureBase64()');
this.test.assert(this.captureBase64('png').length > 0,
'Casper.captureBase64() rendered a page capture as base64');
this.test.assert(this.captureBase64('png', 'ul').length > 0,
'Casper.captureBase64() rendered a capture from a selector as base64');
this.test.assert(this.captureBase64('png', {top: 0, left: 0, width: 30, height: 30}).length > 0,
'Casper.captureBase64() rendered a capture from a clipRect as base64');
});
casper.run(function(self) {
casper.run(function() {
try {
fs.remove(testFile);
} catch(e) {}
this.test.done();
});
......
var utils = require('utils'), t = casper.test;
var utils = require('utils'), t = casper.test, x = require('casper').selectXPath;
t.comment('fileExt()');
(function() {
......@@ -100,6 +100,33 @@ t.comment('isObject()');
t.assertEquals(utils.isObject(null), false, 'isObject() checks for an Object');
})();
t.comment('isValidSelector()');
(function() {
t.assertEquals(utils.isValidSelector({}), false, 'isValidSelector() checks for a valid selector');
t.assertEquals(utils.isValidSelector(""), false, 'isValidSelector() checks for a valid selector');
t.assertEquals(utils.isValidSelector("a"), true, 'isValidSelector() checks for a valid selector');
t.assertEquals(utils.isValidSelector('div#plop form[name="form"] input[type="submit"]'), true, 'isValidSelector() checks for a valid selector');
t.assertEquals(utils.isValidSelector(x('//a')), true, 'isValidSelector() checks for a valid selector');
t.assertEquals(utils.isValidSelector({
type: "css",
path: 'div#plop form[name="form"] input[type="submit"]'
}), true, 'isValidSelector() checks for a valid selector');
t.assertEquals(utils.isValidSelector({
type: "xpath",
path: '//a'
}), true, 'isValidSelector() checks for a valid selector');
t.assertEquals(utils.isValidSelector({
type: "css"
}), false, 'isValidSelector() checks for a valid selector');
t.assertEquals(utils.isValidSelector({
type: "xpath"
}), false, 'isValidSelector() checks for a valid selector');
t.assertEquals(utils.isValidSelector({
type: "css3",
path: "a"
}), false, 'isValidSelector() checks for a valid selector');
})();
t.comment('isWebPage()');
(function() {
var pageModule = require('webpage');
......