phantomjs-binaries 1.8.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +4 -0
- data/Gemfile.lock +18 -0
- data/Rakefile +1 -0
- data/bin/bootstrap.js +342 -0
- data/bin/casperjs +58 -0
- data/bin/phantomjs +13 -0
- data/bin/phantomjs-1.8.0-darwin-x86_64 +0 -0
- data/bin/phantomjs-1.8.0-linux-x86_64 +0 -0
- data/bin/usage.txt +11 -0
- data/lib/phantomjs-binaries/version.rb +5 -0
- data/lib/phantomjs-binaries.rb +7 -0
- data/modules/casper.js +2101 -0
- data/modules/cli.js +138 -0
- data/modules/clientutils.js +781 -0
- data/modules/colorizer.js +130 -0
- data/modules/events.js +259 -0
- data/modules/http.js +70 -0
- data/modules/mouse.js +109 -0
- data/modules/pagestack.js +166 -0
- data/modules/querystring.js +187 -0
- data/modules/tester.js +1161 -0
- data/modules/utils.js +581 -0
- data/modules/vendors/coffee-script.js +8 -0
- data/modules/xunit.js +155 -0
- data/package.json +35 -0
- data/phantomjs-binaries.gemspec +24 -0
- metadata +95 -0
@@ -0,0 +1,166 @@
|
|
1
|
+
/*!
|
2
|
+
* Casper is a navigation utility for PhantomJS.
|
3
|
+
*
|
4
|
+
* Documentation: http://casperjs.org/
|
5
|
+
* Repository: http://github.com/n1k0/casperjs
|
6
|
+
*
|
7
|
+
* Copyright (c) 2011-2012 Nicolas Perriault
|
8
|
+
*
|
9
|
+
* Part of source code is Copyright Joyent, Inc. and other Node contributors.
|
10
|
+
*
|
11
|
+
* Permission is hereby granted, free of charge, to any person obtaining a
|
12
|
+
* copy of this software and associated documentation files (the "Software"),
|
13
|
+
* to deal in the Software without restriction, including without limitation
|
14
|
+
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
15
|
+
* and/or sell copies of the Software, and to permit persons to whom the
|
16
|
+
* Software is furnished to do so, subject to the following conditions:
|
17
|
+
*
|
18
|
+
* The above copyright notice and this permission notice shall be included
|
19
|
+
* in all copies or substantial portions of the Software.
|
20
|
+
*
|
21
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
22
|
+
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
23
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
24
|
+
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
25
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
26
|
+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
27
|
+
* DEALINGS IN THE SOFTWARE.
|
28
|
+
*
|
29
|
+
*/
|
30
|
+
|
31
|
+
/*global CasperError console exports phantom require*/
|
32
|
+
|
33
|
+
var utils = require('utils');
|
34
|
+
var f = utils.format;
|
35
|
+
|
36
|
+
function create() {
|
37
|
+
"use strict";
|
38
|
+
return new Stack();
|
39
|
+
}
|
40
|
+
exports.create = create;
|
41
|
+
|
42
|
+
/**
|
43
|
+
* Popups container. Implements Array prototype.
|
44
|
+
*
|
45
|
+
*/
|
46
|
+
var Stack = function Stack(){};
|
47
|
+
exports.Stack = Stack;
|
48
|
+
|
49
|
+
Stack.prototype = [];
|
50
|
+
|
51
|
+
/**
|
52
|
+
* Cleans the stack from closed popup.
|
53
|
+
*
|
54
|
+
* @param WebPage closed Closed popup page instance
|
55
|
+
* @return Number New stack length
|
56
|
+
*/
|
57
|
+
Stack.prototype.clean = function clean(closed) {
|
58
|
+
"use strict";
|
59
|
+
var closedIndex = -1;
|
60
|
+
this.forEach(function(popup, index) {
|
61
|
+
if (closed === popup) {
|
62
|
+
closedIndex = index;
|
63
|
+
}
|
64
|
+
});
|
65
|
+
if (closedIndex > -1) {
|
66
|
+
this.splice(closedIndex, 1);
|
67
|
+
}
|
68
|
+
return this.length;
|
69
|
+
};
|
70
|
+
|
71
|
+
/**
|
72
|
+
* Finds a popup matching the provided information. Information can be:
|
73
|
+
*
|
74
|
+
* - RegExp: matching page url
|
75
|
+
* - String: strict page url value
|
76
|
+
* - WebPage: a direct WebPage instance
|
77
|
+
*
|
78
|
+
* @param Mixed popupInfo
|
79
|
+
* @return WebPage
|
80
|
+
*/
|
81
|
+
Stack.prototype.find = function find(popupInfo) {
|
82
|
+
"use strict";
|
83
|
+
var popup, type = utils.betterTypeOf(popupInfo);
|
84
|
+
switch (type) {
|
85
|
+
case "regexp":
|
86
|
+
popup = this.findByRegExp(popupInfo);
|
87
|
+
break;
|
88
|
+
case "string":
|
89
|
+
popup = this.findByURL(popupInfo);
|
90
|
+
break;
|
91
|
+
case "qtruntimeobject": // WebPage
|
92
|
+
popup = popupInfo;
|
93
|
+
if (!utils.isWebPage(popup) || !this.some(function(popupPage) {
|
94
|
+
if (popupInfo.id && popupPage.id) {
|
95
|
+
return popupPage.id === popup.id;
|
96
|
+
}
|
97
|
+
return popupPage.url === popup.url;
|
98
|
+
})) {
|
99
|
+
throw new CasperError("Invalid or missing popup.");
|
100
|
+
}
|
101
|
+
break;
|
102
|
+
default:
|
103
|
+
throw new CasperError(f("Invalid popupInfo type: %s.", type));
|
104
|
+
}
|
105
|
+
return popup;
|
106
|
+
};
|
107
|
+
|
108
|
+
/**
|
109
|
+
* Finds the first popup which url matches a given RegExp.
|
110
|
+
*
|
111
|
+
* @param RegExp regexp
|
112
|
+
* @return WebPage
|
113
|
+
*/
|
114
|
+
Stack.prototype.findByRegExp = function findByRegExp(regexp) {
|
115
|
+
"use strict";
|
116
|
+
var popup = this.filter(function(popupPage) {
|
117
|
+
return regexp.test(popupPage.url);
|
118
|
+
})[0];
|
119
|
+
if (!popup) {
|
120
|
+
throw new CasperError(f("Couldn't find popup with url matching pattern %s", regexp));
|
121
|
+
}
|
122
|
+
return popup;
|
123
|
+
};
|
124
|
+
|
125
|
+
/**
|
126
|
+
* Finds the first popup matching a given url.
|
127
|
+
*
|
128
|
+
* @param String url The child WebPage url
|
129
|
+
* @return WebPage
|
130
|
+
*/
|
131
|
+
Stack.prototype.findByURL = function findByURL(string) {
|
132
|
+
"use strict";
|
133
|
+
var popup = this.filter(function(popupPage) {
|
134
|
+
return popupPage.url.indexOf(string) !== -1;
|
135
|
+
})[0];
|
136
|
+
if (!popup) {
|
137
|
+
throw new CasperError(f("Couldn't find popup with url containing '%s'", string));
|
138
|
+
}
|
139
|
+
return popup;
|
140
|
+
};
|
141
|
+
|
142
|
+
/**
|
143
|
+
* Returns a human readable list of current active popup urls.
|
144
|
+
*
|
145
|
+
* @return Array Mapped stack.
|
146
|
+
*/
|
147
|
+
Stack.prototype.list = function list() {
|
148
|
+
"use strict";
|
149
|
+
return this.map(function(popup) {
|
150
|
+
try {
|
151
|
+
return popup.url;
|
152
|
+
} catch (e) {
|
153
|
+
return '<deleted>';
|
154
|
+
}
|
155
|
+
});
|
156
|
+
};
|
157
|
+
|
158
|
+
/**
|
159
|
+
* String representation of current instance.
|
160
|
+
*
|
161
|
+
* @return String
|
162
|
+
*/
|
163
|
+
Stack.prototype.toString = function toString() {
|
164
|
+
"use strict";
|
165
|
+
return f("[Object Stack], having %d popup(s)" % this.length);
|
166
|
+
};
|
@@ -0,0 +1,187 @@
|
|
1
|
+
// Copyright Joyent, Inc. and other Node contributors.
|
2
|
+
//
|
3
|
+
// Permission is hereby granted, free of charge, to any person obtaining a
|
4
|
+
// copy of this software and associated documentation files (the
|
5
|
+
// "Software"), to deal in the Software without restriction, including
|
6
|
+
// without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
8
|
+
// persons to whom the Software is furnished to do so, subject to the
|
9
|
+
// following conditions:
|
10
|
+
//
|
11
|
+
// The above copyright notice and this permission notice shall be included
|
12
|
+
// in all copies or substantial portions of the Software.
|
13
|
+
//
|
14
|
+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
15
|
+
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
17
|
+
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
18
|
+
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
19
|
+
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
20
|
+
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
21
|
+
|
22
|
+
// Query String Utilities
|
23
|
+
|
24
|
+
var QueryString = exports;
|
25
|
+
//var urlDecode = process.binding('http_parser').urlDecode; // phantomjs incompatible
|
26
|
+
|
27
|
+
|
28
|
+
// If obj.hasOwnProperty has been overridden, then calling
|
29
|
+
// obj.hasOwnProperty(prop) will break.
|
30
|
+
// See: https://github.com/joyent/node/issues/1707
|
31
|
+
function hasOwnProperty(obj, prop) {
|
32
|
+
return Object.prototype.hasOwnProperty.call(obj, prop);
|
33
|
+
}
|
34
|
+
|
35
|
+
|
36
|
+
function charCode(c) {
|
37
|
+
return c.charCodeAt(0);
|
38
|
+
}
|
39
|
+
|
40
|
+
|
41
|
+
// a safe fast alternative to decodeURIComponent
|
42
|
+
QueryString.unescapeBuffer = function(s, decodeSpaces) {
|
43
|
+
var out = new Buffer(s.length);
|
44
|
+
var state = 'CHAR'; // states: CHAR, HEX0, HEX1
|
45
|
+
var n, m, hexchar;
|
46
|
+
|
47
|
+
for (var inIndex = 0, outIndex = 0; inIndex <= s.length; inIndex++) {
|
48
|
+
var c = s.charCodeAt(inIndex);
|
49
|
+
switch (state) {
|
50
|
+
case 'CHAR':
|
51
|
+
switch (c) {
|
52
|
+
case charCode('%'):
|
53
|
+
n = 0;
|
54
|
+
m = 0;
|
55
|
+
state = 'HEX0';
|
56
|
+
break;
|
57
|
+
case charCode('+'):
|
58
|
+
if (decodeSpaces) c = charCode(' ');
|
59
|
+
// pass thru
|
60
|
+
default:
|
61
|
+
out[outIndex++] = c;
|
62
|
+
break;
|
63
|
+
}
|
64
|
+
break;
|
65
|
+
|
66
|
+
case 'HEX0':
|
67
|
+
state = 'HEX1';
|
68
|
+
hexchar = c;
|
69
|
+
if (charCode('0') <= c && c <= charCode('9')) {
|
70
|
+
n = c - charCode('0');
|
71
|
+
} else if (charCode('a') <= c && c <= charCode('f')) {
|
72
|
+
n = c - charCode('a') + 10;
|
73
|
+
} else if (charCode('A') <= c && c <= charCode('F')) {
|
74
|
+
n = c - charCode('A') + 10;
|
75
|
+
} else {
|
76
|
+
out[outIndex++] = charCode('%');
|
77
|
+
out[outIndex++] = c;
|
78
|
+
state = 'CHAR';
|
79
|
+
break;
|
80
|
+
}
|
81
|
+
break;
|
82
|
+
|
83
|
+
case 'HEX1':
|
84
|
+
state = 'CHAR';
|
85
|
+
if (charCode('0') <= c && c <= charCode('9')) {
|
86
|
+
m = c - charCode('0');
|
87
|
+
} else if (charCode('a') <= c && c <= charCode('f')) {
|
88
|
+
m = c - charCode('a') + 10;
|
89
|
+
} else if (charCode('A') <= c && c <= charCode('F')) {
|
90
|
+
m = c - charCode('A') + 10;
|
91
|
+
} else {
|
92
|
+
out[outIndex++] = charCode('%');
|
93
|
+
out[outIndex++] = hexchar;
|
94
|
+
out[outIndex++] = c;
|
95
|
+
break;
|
96
|
+
}
|
97
|
+
out[outIndex++] = 16 * n + m;
|
98
|
+
break;
|
99
|
+
}
|
100
|
+
}
|
101
|
+
|
102
|
+
// TODO support returning arbitrary buffers.
|
103
|
+
|
104
|
+
return out.slice(0, outIndex - 1);
|
105
|
+
};
|
106
|
+
|
107
|
+
|
108
|
+
QueryString.unescape = function(s, decodeSpaces) {
|
109
|
+
return QueryString.unescapeBuffer(s, decodeSpaces).toString();
|
110
|
+
};
|
111
|
+
|
112
|
+
|
113
|
+
QueryString.escape = function(str) {
|
114
|
+
return encodeURIComponent(str);
|
115
|
+
};
|
116
|
+
|
117
|
+
var stringifyPrimitive = function(v) {
|
118
|
+
switch (typeof v) {
|
119
|
+
case 'string':
|
120
|
+
return v;
|
121
|
+
|
122
|
+
case 'boolean':
|
123
|
+
return v ? 'true' : 'false';
|
124
|
+
|
125
|
+
case 'number':
|
126
|
+
return isFinite(v) ? v : '';
|
127
|
+
|
128
|
+
default:
|
129
|
+
return '';
|
130
|
+
}
|
131
|
+
};
|
132
|
+
|
133
|
+
|
134
|
+
QueryString.stringify = QueryString.encode = function(obj, sep, eq, name) {
|
135
|
+
sep = sep || '&';
|
136
|
+
eq = eq || '=';
|
137
|
+
obj = (obj === null) ? undefined : obj;
|
138
|
+
|
139
|
+
switch (typeof obj) {
|
140
|
+
case 'object':
|
141
|
+
return Object.keys(obj).map(function(k) {
|
142
|
+
if (Array.isArray(obj[k])) {
|
143
|
+
return obj[k].map(function(v) {
|
144
|
+
return QueryString.escape(stringifyPrimitive(k)) +
|
145
|
+
eq +
|
146
|
+
QueryString.escape(stringifyPrimitive(v));
|
147
|
+
}).join(sep);
|
148
|
+
} else {
|
149
|
+
return QueryString.escape(stringifyPrimitive(k)) +
|
150
|
+
eq +
|
151
|
+
QueryString.escape(stringifyPrimitive(obj[k]));
|
152
|
+
}
|
153
|
+
}).join(sep);
|
154
|
+
|
155
|
+
default:
|
156
|
+
if (!name) return '';
|
157
|
+
return QueryString.escape(stringifyPrimitive(name)) + eq +
|
158
|
+
QueryString.escape(stringifyPrimitive(obj));
|
159
|
+
}
|
160
|
+
};
|
161
|
+
|
162
|
+
// Parse a key=val string.
|
163
|
+
QueryString.parse = QueryString.decode = function(qs, sep, eq) {
|
164
|
+
sep = sep || '&';
|
165
|
+
eq = eq || '=';
|
166
|
+
var obj = {};
|
167
|
+
|
168
|
+
if (typeof qs !== 'string' || qs.length === 0) {
|
169
|
+
return obj;
|
170
|
+
}
|
171
|
+
|
172
|
+
qs.split(sep).forEach(function(kvp) {
|
173
|
+
var x = kvp.split(eq);
|
174
|
+
var k = QueryString.unescape(x[0], true);
|
175
|
+
var v = QueryString.unescape(x.slice(1).join(eq), true);
|
176
|
+
|
177
|
+
if (!hasOwnProperty(obj, k)) {
|
178
|
+
obj[k] = v;
|
179
|
+
} else if (!Array.isArray(obj[k])) {
|
180
|
+
obj[k] = [obj[k], v];
|
181
|
+
} else {
|
182
|
+
obj[k].push(v);
|
183
|
+
}
|
184
|
+
});
|
185
|
+
|
186
|
+
return obj;
|
187
|
+
};
|