Skip to content
This repository has been archived by the owner on Sep 21, 2022. It is now read-only.

Commit

Permalink
Support multiple elements and actions
Browse files Browse the repository at this point in the history
  • Loading branch information
Sergey Tatarintsev committed Feb 19, 2014
1 parent e1a8b10 commit 8879181
Show file tree
Hide file tree
Showing 9 changed files with 197 additions and 61 deletions.
36 changes: 15 additions & 21 deletions lib/browser.js
Expand Up @@ -5,24 +5,6 @@ var inherit = require('inherit'),
Image = require('./image'),
By = webdriver.By;

function wdToQ(wdPromise) {
return wdPromise;
//var d = q.defer();
//wdPromise.then(
//function() {
//console.log('here', '123');
//console.log(arguments);
//d.resolve.apply(d, arguments);
//},

//function() {
//console.log('here', '456');
//d.reject.apply(d, arguments);
//}
//);
//return d.promise;
}

module.exports = inherit({
__constructor: function() {
this._driver = new webdriver.Builder().
Expand All @@ -31,22 +13,34 @@ module.exports = inherit({
},

open: function(url) {
return wdToQ(this._driver.get(url));
return this._driver.get(url);
},

findElements: function(elements) {
var result = {};
Object.keys(elements).forEach(function(key) {
result[key] = this._driver.findElement(By.css(elements[key]));
}, this);
return result;
},

findElement: function(selector) {
return wdToQ(this._driver.findElement(By.css(selector)));
return this._driver.findElement(By.css(selector));
},

takeScreenshot: function() {
return wdToQ(this._driver.takeScreenshot())
return this._driver.takeScreenshot()
.then(function (base64) {
return new Image(new Buffer(base64, 'base64'));
});
},

quit: function() {
return this._driver.quit();
},

createActionSequence: function() {
return new webdriver.ActionSequence(this._driver);
}

});
55 changes: 25 additions & 30 deletions lib/element-rect.js
@@ -1,24 +1,29 @@
'use strict';
var q = require('q'),
Rect = require('./geometery/rect');

exports.getMultiple = function getMultiple(elements) {
return q.all(Object.keys(elements).map(function(key) {
return exports.get(elements[key]);
}))
.then(function(rects) {
return rects.reduce(function(first, second) {
return first.merge(second);
});
});
};

exports.get = function(element) {
exports.get = function get(element) {
return element.getLocation()
.then(function(pos) {
return element.getSize().then(function(size) {
return {
x: pos.x,
y: pos.y,
width: size.width,
height: size.height
};
return new Rect(pos.x, pos.y, size.width, size.height);
});
})
.then(function(rect) {
return element.getCssValue('box-shadow').then(function(boxShadow) {
var shadows = parseBoxShadow(boxShadow);
shadows.forEach(function(shadow) {
addBoxShadowSize(rect, shadow);
});
return rect;
return shadows.reduce(addBoxShadowRect, rect);
});
});
};
Expand All @@ -44,23 +49,13 @@ function parseBoxShadow(value) {
return results;
}

function addBoxShadowSize(box, shadow) {
if (shadow.offsetX > 0) {
box.width += shadow.offsetX;
} else {
box.x -= shadow.offsetX;
}

if (shadow.offsetY > 0) {
box.height += shadow.offsetY;
} else {
box.y -= shadow.offsetY;
}

//TODO: negative spread

box.x -= shadow.spreadRadius + shadow.blurRadius;
box.y -= shadow.spreadRadius + shadow.blurRadius;
box.width += 2 * (shadow.spreadRadius + shadow.blurRadius);
box.height += 2 * (shadow.spreadRadius + shadow.blurRadius);
function addBoxShadowRect(rect, shadow) {
var size = shadow.blurRadius + shadow.spreadRadius,
shadowRect = new Rect(
rect.x + shadow.offsetX - size,
rect.y + shadow.offsetY - size,
rect.width - shadow.offsetX + 2 * size,
rect.height - shadow.offsetY + 2 *size
);
return rect.merge(shadowRect);
}
45 changes: 45 additions & 0 deletions lib/geometery/rect.js
@@ -0,0 +1,45 @@
'use strict';
var inherit = require('inherit');

var Rect = inherit({

//it's ok to have 4 parameters for rect class constructor -
//purpose and ordering of such params are typical
/*jshint maxparams: 4*/
__constructor: function(x, y, width, height) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;

Object.defineProperties(this, {
right: {
get: function() {
return this.x + this.width;
}
},

bottom: {
get: function() {
return this.y + this.height;
}
}
});

},

merge: function(other) {
var x = Math.min(this.x, other.x),
y = Math.min(this.y, other.y);

return new Rect(
x,
y,
Math.max(this.right, other.right) - x,
Math.max(this.bottom, other.bottom) - y
);
}

});

module.exports = Rect;
8 changes: 4 additions & 4 deletions lib/plan.js
Expand Up @@ -18,8 +18,8 @@ var Plan = module.exports = inherit({
return this;
},

setElement: function setElement(selector) {
this.selector = selector;
setElements: function setElement(elements) {
this.elements = elements;
return this;
},

Expand All @@ -38,8 +38,8 @@ var Plan = module.exports = inherit({
return Object.keys(this._states);
},

toState: function toState(name, element, page) {
return this._states[name].call(this, element, page);
toState: function toState(name, actions, elements) {
return this._states[name].call(this, actions, elements);
}

}, {
Expand Down
11 changes: 7 additions & 4 deletions lib/screen-shooter.js
Expand Up @@ -19,15 +19,18 @@ module.exports = inherit(Runner, {
this.emit('beginCapture', plan, state);
return browser.open(this.config.getAbsoluteUrl(plan.url))
.then(function() {
return browser.findElement(plan.selector);
return browser.findElements(plan.elements);
})
.then(function(element) {
return plan.toState(state, element, this._browser)
.then(function(elements) {
var actions = browser.createActionSequence();

plan.toState(state, actions, elements);
return actions.perform()
.then(function() {
return browser.takeScreenshot();
})
.then(function(image) {
return elementRect.get(element)
return elementRect.getMultiple(elements)
.then(function(rect) {
return image.crop(rect);
});
Expand Down
7 changes: 5 additions & 2 deletions package.json
Expand Up @@ -17,9 +17,12 @@
"temp": "~0.6.0",
"lodash": "~2.4.1"
},
"devDependencies": {},
"devDependencies": {
"mocha": "~1.17.1",
"must": "~0.11.0"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
"test": "mocha"
},
"author": "",
"license": "MIT",
Expand Down
27 changes: 27 additions & 0 deletions test/.jshintrc
@@ -0,0 +1,27 @@
{
"bitwise": true,
"camelcase": true,
"curly": true,
"eqeqeq": true,
"freeze": true,
"immed": true,
"indent": 4,
"latedef": "nofunc",
"newcap": true,
"noarg": true,
"nonew": true,
"quotmark": "single",
"undef": true,
"unused": "vars",
"strict": true,
"trailing": true,
"maxparams": 3,
"node": true,
"predef": {
"describe": false,
"it": false,
"before": false,
"beforeEach": false,
"afterEach": false
}
}
1 change: 1 addition & 0 deletions test/mocha.opts
@@ -0,0 +1 @@
--require must
68 changes: 68 additions & 0 deletions test/rect.test.js
@@ -0,0 +1,68 @@
'use strict';
var Rect = require('../lib/geometery/rect');

describe('rect', function() {
var rect;

beforeEach(function() {
rect = new Rect(10, 20, 30, 40);
});

it('should have correct x', function() {
rect.x.must.equal(10);
});

it('should have correct y', function() {
rect.y.must.equal(20);
});

it('should report correct width', function() {
rect.width.must.equal(30);
});

it('should report correct height', function() {
rect.height.must.equal(40);
});

it('should report correct right', function() {
rect.right.must.equal(40);
});

it('should report correct bottom', function() {
rect.bottom.must.equal(60);
});

describe('#merge', function() {
it('should pick smaller x', function() {
rect.merge(new Rect(1, 0, 0, 0)).x.must.equal(1);
});

it('should not pick larger x', function() {
rect.merge(new Rect(11, 0, 0, 0)).x.must.equal(10);
});

it('should pick smaller y', function() {
rect.merge(new Rect(0, 1, 0, 0)).y.must.equal(1);
});

it('should not pick larger y', function() {
rect.merge(new Rect(0, 25, 0, 0)).y.must.equal(20);
});

it('should pick larger right', function() {
rect.merge(new Rect(0, 0, 100, 40)).right.must.equal(100);
});

it('should not pick smaller right', function() {
rect.merge(new Rect(15, 0, 10, 40)).right.must.equal(40);
});

it('should pick larger bottom', function() {
rect.merge(new Rect(0, 10, 0, 55)).bottom.must.equal(65);
});

it('should not pick smaller bottom', function() {
rect.merge(new Rect(0, 25, 0, 30)).bottom.must.equal(60);
});
});
});

0 comments on commit 8879181

Please sign in to comment.