-
Notifications
You must be signed in to change notification settings - Fork 7
/
pediff.js
156 lines (134 loc) · 5.59 KB
/
pediff.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
var Casper = require(phantom.casperPath + '/modules/casper').Casper,
utils = require(phantom.casperPath + '/modules/utils'),
fs = require('fs');
function Pediff(){
Pediff.super_.apply(this, arguments);
}
utils.inherits(Pediff, Casper);
/**
* Set the environment that the app is currently working in (eg. current, candidate).
* Used for establishing output path for the page screenshots.
*
* @param {string} environment
*/
Pediff.prototype.setEnvironment = function(environment){
this.environment = environment;
};
/**
* Set the viewport size that the app is currently working with.
*
* @param {string} viewportSize
*/
Pediff.prototype.setViewportSize = function(viewportSize){
this.viewportSize = viewportSize;
};
/**
* Merge global config object from /config directory with current task specific options, set up
* necessary properties.
*
* @param {Object} task
*/
Pediff.prototype.init = function(task){
this.config = utils.mergeObjects(require('./config'), task.config);
utils.mergeObjects(this.options, this.config.options);
this.options.onResourceRequested = this.setMocks;
this.execute = task.execute;
};
/**
* Intercept requests matching keys from config.mocks and replace responses with corresponding
* mocks from /mocks directory.
* @see https://github.com/ariya/phantomjs/wiki/API-Reference-WebPage#wiki-webpage-onResourceRequested
*
* @param {Object} pd Pediff instance
* @param {Object} requestData
* @param {Object} networkRequest
*/
Pediff.prototype.setMocks = function(pd, requestData, networkRequest){
for (var key in this.config.mocks){
if (requestData.url.split('/').pop() === key){
networkRequest.changeUrl('./mocks/' + this.config.mocks[key]);
break;
}
}
};
/**
* Inject all custom CSS rules into head
* @param {Object} pd Pediff instance
*/
Pediff.prototype.preExecute = function(pd){
var styleString = '<style>';
for (var key in this.config.css){
styleString += key + ' { ' + this.config.css[key] + ' } ';
}
styleString += '</style>';
this.saved = false;
this.evaluate(function(styleString) {
$('head').append($(styleString));
}, styleString);
};
/**
* Convenience wrapper method for casper.capture and casper.captureSelector methods. Redirects output
* to appropriate environment directory.
* @see http://casperjs.org/api.html#casper.capture
*
* @param {string} filename name of the file to be written
* @param {string} selector optional css or xpath selector
*/
Pediff.prototype.save = function(filename, selector){
filename = this.config.package + ((filename) ? '@' + filename : '');
this.wait(500,(function(that){
if (that.options.verbose){
console.log('[' + that.config.environments[that.environment] + (that.config.path || '') + '@' + that.viewportSize.width + 'x' +
that.viewportSize.height + '] ' + filename + '.' + that.config.output.extension);
}
//save HTML for debugging purposes
fs.write(that.environment + '/html/' + that.viewportSize.width + 'x' +
that.viewportSize.height + '_' + filename + '.html',that.getHTML(),'w');
if (selector === undefined){
that.capture(that.environment + '/' + that.viewportSize.width + 'x' +
that.viewportSize.height + '_' + filename + '.' + that.config.output.extension);
} else {
that.captureSelector(that.environment + '/' + that.viewportSize.width + 'x' +
that.viewportSize.height + '_' + filename + '.' + that.config.output.extension,
selector);
}
that.saved = true;
that.captureMedia(filename);
})(this));
};
/**
* Helper method allowing to use current stylesheet sections designed for specific media (such as print, handheld, ...)
* as the default stylesheet. Used internally.
* @param {string} filename name of the file to be written
*/
Pediff.prototype.captureMedia = function(filename){
for(var media in this.config.media) {
if(this.config.media[media] && typeof(this['media_'+media+'_'+this.environment]) == 'undefined') {
this['media_'+media+'_'+this.environment] = true;
this.viewport(this.config.media[media].width, this.config.media[media].height, function(){
var data = this.evaluate(function() {
var $stylesheet = $('link[rel="stylesheet"][href*="main"]');
var url = $stylesheet.attr('href');
$stylesheet.remove();
return __utils__.sendAJAX('http:'+url, 'GET', null, false);
});
var styleString = '<style>'+data.replace('@media '+media,'@media screen')+'</style>';
this.evaluate(function(styleString) {
$('head').append($(styleString));
}, styleString);
this.capture(this.environment + '/' + this.config.media[media].width + 'x' +
this.config.media[media].height + '_' + media + '_' + filename + '.' + this.config.output.extension);
});
}
}
}
Pediff.prototype.postExecute = function(){
if(!this.saved) {
console.log('[warning][' + this.environment + '@' + this.viewportSize.width + 'x' +
this.viewportSize.height + '] ' + this.config.package + '.' + this.config.output.extension + ' was not saved');
//save HTML for debugging purposes
fs.write(this.environment + '/html/failed/' + this.viewportSize.width + 'x' +
this.viewportSize.height + '_' + this.config.package + '.html',this.getHTML(),'w');
}
}
module.exports = Pediff;