Skip to content
Toggle navigation
Toggle navigation
This project
Loading...
Sign in
John McEleney
/
casperjs
Go to a project
Toggle navigation
Toggle navigation pinning
Projects
Groups
Snippets
Help
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Network
Create a new issue
Builds
Commits
Issue Boards
Files
Commits
Network
Compare
Branches
Tags
Commit
301d6345
...
301d63454d0f1bd9a337ce02f585d2a7d23828dd
authored
2011-12-24 16:54:22 +0100
by
Nicolas Perriault
Browse Files
Options
Browse Files
Tag
Download
Email Patches
Plain Diff
continued migration to a full require() based layout
1 parent
d5ff7c42
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
227 additions
and
176 deletions
casperjs
lib/casper.js
lib/clientutils.js
lib/colorizer.js
lib/injector.js
lib/tester.js
lib/utils.js
lib/xunit.js
casperjs
View file @
301d634
...
...
@@ -106,6 +106,28 @@ phantom.casperArgs = (function(cliArgs) {
return extract;
})(phantom.args);
var sourceIds = {};
// Inspired by phantomjs-nodify: https://github.com/jgonera/phantomjs-nodify/
// TODO: remoive when phantomjs has js engine upgrade
if (!new Error().hasOwnProperty('stack')) {
Object.defineProperty(Error.prototype, 'stack', {
set: function(string) {
this._stack = string;
},
get: function() {
if (this._stack) {
return this._stack;
} else if (this.fileName || this.sourceId) {
return this.toString() + '\nat ' + getErrorMessage(this);
}
return this.toString() + '\nat unknown';
},
configurable: true,
enumerable: true
});
}
// Inspired by phantomjs-nodify: https://github.com/jgonera/phantomjs-nodify/
// TODO: remove when PhantomJS has full module support
require = (function(require, requireDir) {
...
...
@@ -159,7 +181,14 @@ require = (function(require, requireDir) {
return requireCache[file].exports;
}
code = fs.read(file);
if (file.match(/\.coffee$/)) {
if (file.match(/\.js$/i)) {
try {
// TODO: esprima syntax check
} catch (e) {
e.fileName = file;
throw e;
}
} else if (file.match(/\.coffee$/i)) {
try {
code = CoffeeScript.compile(code);
} catch (e) {
...
...
@@ -168,12 +197,12 @@ require = (function(require, requireDir) {
}
}
// a trick to associate Error's sourceId with file
//
code += ";throw new Error('__sourceId__');";
code += ";throw new Error('__sourceId__');";
try {
fn = new Function('module', 'exports', code);
fn(module, module.exports);
} catch (e) {
if (
typeof sourceIds === "object" &&
!sourceIds.hasOwnProperty(e.sourceId)) {
if (!sourceIds.hasOwnProperty(e.sourceId)) {
sourceIds[e.sourceId] = file;
}
if (e.message !== '__sourceId__') {
...
...
lib/casper.js
View file @
301d634
...
...
@@ -28,12 +28,9 @@
var
utils
=
require
(
'./lib/utils'
);
exports
.
create
=
create
;
exports
.
Casper
=
Casper
;
function
create
(
options
)
{
exports
.
create
=
function
(
options
)
{
return
new
Casper
(
options
);
}
}
;
/**
* Main Casper object.
...
...
@@ -89,7 +86,7 @@ var Casper = function(options) {
warning
:
'COMMENT'
,
error
:
'ERROR'
};
this
.
options
=
mergeObjects
(
this
.
defaults
,
options
);
this
.
options
=
utils
.
mergeObjects
(
this
.
defaults
,
options
);
this
.
page
=
null
;
this
.
pendingWait
=
false
;
this
.
requestUrl
=
'about:blank'
;
...
...
@@ -152,7 +149,7 @@ Casper.prototype = {
capture
:
function
(
targetFile
,
clipRect
)
{
var
previousClipRect
;
if
(
clipRect
)
{
if
(
!
isType
(
clipRect
,
"object"
))
{
if
(
!
utils
.
isType
(
clipRect
,
"object"
))
{
throw
new
Error
(
"clipRect must be an Object instance."
);
}
previousClipRect
=
this
.
page
.
clipRect
;
...
...
@@ -206,13 +203,13 @@ Casper.prototype = {
return
;
}
var
step
=
self
.
steps
[
self
.
step
++
];
if
(
isType
(
step
,
"function"
))
{
if
(
utils
.
isType
(
step
,
"function"
))
{
self
.
runStep
(
step
);
}
else
{
self
.
result
.
time
=
new
Date
().
getTime
()
-
self
.
startTime
;
self
.
log
(
"Done "
+
self
.
steps
.
length
+
" steps in "
+
self
.
result
.
time
+
'ms.'
,
"info"
);
clearInterval
(
self
.
checker
);
if
(
isType
(
onComplete
,
"function"
))
{
if
(
utils
.
isType
(
onComplete
,
"function"
))
{
try
{
onComplete
.
call
(
self
,
self
);
}
catch
(
err
)
{
...
...
@@ -234,7 +231,7 @@ Casper.prototype = {
* @return Boolean
*/
click
:
function
(
selector
,
fallbackToHref
)
{
fallbackToHref
=
isType
(
fallbackToHref
,
"undefined"
)
?
true
:
!!
fallbackToHref
;
fallbackToHref
=
utils
.
isType
(
fallbackToHref
,
"undefined"
)
?
true
:
!!
fallbackToHref
;
this
.
log
(
"click on selector: "
+
selector
,
"debug"
);
return
this
.
evaluate
(
function
(
selector
,
fallbackToHref
)
{
return
__utils__
.
click
(
selector
,
fallbackToHref
);
...
...
@@ -252,10 +249,10 @@ Casper.prototype = {
* @return Function The final step function
*/
createStep
:
function
(
fn
,
options
)
{
if
(
!
isType
(
fn
,
"function"
))
{
if
(
!
utils
.
isType
(
fn
,
"function"
))
{
throw
new
Error
(
"createStep(): a step definition must be a function"
);
}
fn
.
options
=
isType
(
options
,
"object"
)
?
options
:
{};
fn
.
options
=
utils
.
isType
(
options
,
"object"
)
?
options
:
{};
return
fn
;
},
...
...
@@ -293,9 +290,9 @@ Casper.prototype = {
die
:
function
(
message
,
status
)
{
this
.
result
.
status
=
'error'
;
this
.
result
.
time
=
new
Date
().
getTime
()
-
this
.
startTime
;
message
=
isType
(
message
,
"string"
)
&&
message
.
length
>
0
?
message
:
DEFAULT_DIE_MESSAGE
;
message
=
utils
.
isType
(
message
,
"string"
)
&&
message
.
length
>
0
?
message
:
DEFAULT_DIE_MESSAGE
;
this
.
log
(
message
,
"error"
);
if
(
isType
(
this
.
options
.
onDie
,
"function"
))
{
if
(
utils
.
isType
(
this
.
options
.
onDie
,
"function"
))
{
this
.
options
.
onDie
.
call
(
this
,
this
,
message
,
status
);
}
return
this
.
exit
(
Number
(
status
)
>
0
?
Number
(
status
)
:
1
);
...
...
@@ -327,7 +324,7 @@ Casper.prototype = {
* @return Casper
*/
each
:
function
(
array
,
fn
)
{
if
(
!
isType
(
array
,
"array"
))
{
if
(
!
utils
.
isType
(
array
,
"array"
))
{
this
.
log
(
"each() only works with arrays"
,
"error"
);
return
this
;
}
...
...
@@ -374,7 +371,7 @@ Casper.prototype = {
* @see WebPage#evaluate
*/
evaluate
:
function
(
fn
,
context
)
{
context
=
isType
(
context
,
"object"
)
?
context
:
{};
context
=
utils
.
isType
(
context
,
"object"
)
?
context
:
{};
var
newFn
=
require
(
'./lib/injector'
).
create
(
fn
).
process
(
context
);
return
this
.
page
.
evaluate
(
newFn
);
},
...
...
@@ -454,10 +451,10 @@ Casper.prototype = {
*/
fill
:
function
(
selector
,
vals
,
submit
)
{
submit
=
submit
===
true
?
submit
:
false
;
if
(
!
isType
(
selector
,
"string"
)
||
!
selector
.
length
)
{
if
(
!
utils
.
isType
(
selector
,
"string"
)
||
!
selector
.
length
)
{
throw
new
Error
(
"Form selector must be a non-empty string"
);
}
if
(
!
isType
(
vals
,
"object"
))
{
if
(
!
utils
.
isType
(
vals
,
"object"
))
{
throw
new
Error
(
"Form values must be provided as an object"
);
}
var
fillResults
=
this
.
evaluate
(
function
(
selector
,
values
)
{
...
...
@@ -569,7 +566,7 @@ Casper.prototype = {
log
:
function
(
message
,
level
,
space
)
{
level
=
level
&&
this
.
logLevels
.
indexOf
(
level
)
>
-
1
?
level
:
"debug"
;
space
=
space
?
space
:
"phantom"
;
if
(
level
===
"error"
&&
isType
(
this
.
options
.
onError
,
"function"
))
{
if
(
level
===
"error"
&&
utils
.
isType
(
this
.
options
.
onError
,
"function"
))
{
this
.
options
.
onError
.
call
(
this
,
this
,
message
,
space
);
}
if
(
this
.
logLevels
.
indexOf
(
level
)
<
this
.
logLevels
.
indexOf
(
this
.
options
.
logLevel
))
{
...
...
@@ -581,7 +578,7 @@ Casper.prototype = {
message
:
message
,
date
:
new
Date
().
toString
()
};
if
(
level
in
this
.
logFormats
&&
isType
(
this
.
logFormats
[
level
],
"function"
))
{
if
(
level
in
this
.
logFormats
&&
utils
.
isType
(
this
.
logFormats
[
level
],
"function"
))
{
message
=
this
.
logFormats
[
level
](
message
,
level
,
space
);
}
else
{
var
levelStr
=
this
.
colorizer
.
colorize
(
'['
+
level
+
']'
,
this
.
logStyles
[
level
]);
...
...
@@ -603,7 +600,7 @@ Casper.prototype = {
* @return Casper
*/
open
:
function
(
location
,
options
)
{
options
=
isType
(
options
,
"object"
)
?
options
:
{};
options
=
utils
.
isType
(
options
,
"object"
)
?
options
:
{};
this
.
requestUrl
=
location
;
// http auth
var
httpAuthMatch
=
location
.
match
(
/^https
?
:
\/\/(
.+
)
:
(
.+
)
@/i
);
...
...
@@ -637,7 +634,7 @@ Casper.prototype = {
*/
resourceExists
:
function
(
test
)
{
var
testFn
;
if
(
isType
(
test
,
"string"
))
{
if
(
utils
.
isType
(
test
,
"string"
))
{
testFn
=
function
(
res
)
{
return
res
.
url
.
search
(
test
)
!==
-
1
;
};
...
...
@@ -670,17 +667,17 @@ Casper.prototype = {
* @param Function step
*/
runStep
:
function
(
step
)
{
var
skipLog
=
isType
(
step
.
options
,
"object"
)
&&
step
.
options
.
skipLog
===
true
;
var
skipLog
=
utils
.
isType
(
step
.
options
,
"object"
)
&&
step
.
options
.
skipLog
===
true
;
var
stepInfo
=
"Step "
+
(
this
.
step
)
+
"/"
+
this
.
steps
.
length
;
var
stepResult
;
if
(
!
skipLog
)
{
this
.
log
(
stepInfo
+
' '
+
this
.
getCurrentUrl
()
+
' (HTTP '
+
this
.
currentHTTPStatus
+
')'
,
"info"
);
}
if
(
isType
(
this
.
options
.
stepTimeout
,
"number"
)
&&
this
.
options
.
stepTimeout
>
0
)
{
if
(
utils
.
isType
(
this
.
options
.
stepTimeout
,
"number"
)
&&
this
.
options
.
stepTimeout
>
0
)
{
var
stepTimeoutCheckInterval
=
setInterval
(
function
(
self
,
start
,
stepNum
)
{
if
(
new
Date
().
getTime
()
-
start
>
self
.
options
.
stepTimeout
)
{
if
(
self
.
step
==
stepNum
)
{
if
(
isType
(
self
.
options
.
onStepTimeout
,
"function"
))
{
if
(
utils
.
isType
(
self
.
options
.
onStepTimeout
,
"function"
))
{
self
.
options
.
onStepTimeout
.
call
(
self
,
self
);
}
else
{
self
.
die
(
"Maximum step execution timeout exceeded for step "
+
stepNum
,
"error"
);
...
...
@@ -699,7 +696,7 @@ Casper.prototype = {
throw
e
;
}
}
if
(
isType
(
this
.
options
.
onStepComplete
,
"function"
))
{
if
(
utils
.
isType
(
this
.
options
.
onStepComplete
,
"function"
))
{
this
.
options
.
onStepComplete
.
call
(
this
,
this
,
stepResult
);
}
if
(
!
skipLog
)
{
...
...
@@ -718,7 +715,7 @@ Casper.prototype = {
if
(
!
this
.
started
)
{
throw
new
Error
(
"Casper must be started in order to use the setHttpAuth() method"
);
}
if
(
!
isType
(
username
,
"string"
)
||
!
isType
(
password
,
"string"
))
{
if
(
!
utils
.
isType
(
username
,
"string"
)
||
!
utils
.
isType
(
password
,
"string"
))
{
throw
new
Error
(
"Both username and password must be strings"
);
}
this
.
page
.
settings
.
userName
=
username
;
...
...
@@ -746,37 +743,37 @@ Casper.prototype = {
this
.
options
.
logLevel
=
"warning"
;
}
// WebPage
if
(
!
isWebPage
(
this
.
page
))
{
if
(
isWebPage
(
this
.
options
.
page
))
{
if
(
!
utils
.
isWebPage
(
this
.
page
))
{
if
(
utils
.
isWebPage
(
this
.
options
.
page
))
{
this
.
page
=
this
.
options
.
page
;
}
else
{
this
.
page
=
createPage
(
this
);
}
}
this
.
page
.
settings
=
mergeObjects
(
this
.
page
.
settings
,
this
.
options
.
pageSettings
);
if
(
isType
(
this
.
options
.
clipRect
,
"object"
))
{
this
.
page
.
settings
=
utils
.
mergeObjects
(
this
.
page
.
settings
,
this
.
options
.
pageSettings
);
if
(
utils
.
isType
(
this
.
options
.
clipRect
,
"object"
))
{
this
.
page
.
clipRect
=
this
.
options
.
clipRect
;
}
if
(
isType
(
this
.
options
.
viewportSize
,
"object"
))
{
if
(
utils
.
isType
(
this
.
options
.
viewportSize
,
"object"
))
{
this
.
page
.
viewportSize
=
this
.
options
.
viewportSize
;
}
this
.
started
=
true
;
if
(
isType
(
this
.
options
.
timeout
,
"number"
)
&&
this
.
options
.
timeout
>
0
)
{
if
(
utils
.
isType
(
this
.
options
.
timeout
,
"number"
)
&&
this
.
options
.
timeout
>
0
)
{
this
.
log
(
"Execution timeout set to "
+
this
.
options
.
timeout
+
'ms'
,
"info"
);
setTimeout
(
function
(
self
)
{
if
(
isType
(
self
.
options
.
onTimeout
,
"function"
))
{
if
(
utils
.
isType
(
self
.
options
.
onTimeout
,
"function"
))
{
self
.
options
.
onTimeout
.
call
(
self
,
self
);
}
else
{
self
.
die
(
"Timeout of "
+
self
.
options
.
timeout
+
"ms exceeded, exiting."
);
}
},
this
.
options
.
timeout
,
this
);
}
if
(
isType
(
this
.
options
.
onPageInitialized
,
"function"
))
{
if
(
utils
.
isType
(
this
.
options
.
onPageInitialized
,
"function"
))
{
this
.
log
(
"Post-configuring WebPage instance"
,
"debug"
);
this
.
options
.
onPageInitialized
.
call
(
this
,
this
.
page
);
}
if
(
isType
(
location
,
"string"
)
&&
location
.
length
>
0
)
{
return
this
.
thenOpen
(
location
,
isType
(
then
,
"function"
)
?
then
:
this
.
createStep
(
function
(
self
)
{
if
(
utils
.
isType
(
location
,
"string"
)
&&
location
.
length
>
0
)
{
return
this
.
thenOpen
(
location
,
utils
.
isType
(
then
,
"function"
)
?
then
:
this
.
createStep
(
function
(
self
)
{
self
.
log
(
"start page is loaded"
,
"debug"
);
}));
}
...
...
@@ -793,7 +790,7 @@ Casper.prototype = {
if
(
!
this
.
started
)
{
throw
new
Error
(
"Casper not started; please use Casper#start"
);
}
if
(
!
isType
(
step
,
"function"
))
{
if
(
!
utils
.
isType
(
step
,
"function"
))
{
throw
new
Error
(
"You can only define a step as a function"
);
}
// check if casper is running
...
...
@@ -832,7 +829,7 @@ Casper.prototype = {
this
.
then
(
function
(
self
)
{
self
.
click
(
selector
,
fallbackToHref
);
});
return
isType
(
then
,
"function"
)
?
this
.
then
(
then
)
:
this
;
return
utils
.
isType
(
then
,
"function"
)
?
this
.
then
(
then
)
:
this
;
},
/**
...
...
@@ -864,7 +861,7 @@ Casper.prototype = {
},
{
skipLog
:
true
}));
return
isType
(
then
,
"function"
)
?
this
.
then
(
then
)
:
this
;
return
utils
.
isType
(
then
,
"function"
)
?
this
.
then
(
then
)
:
this
;
},
/**
...
...
@@ -890,7 +887,7 @@ Casper.prototype = {
* @return Casper
*/
viewport
:
function
(
width
,
height
)
{
if
(
!
isType
(
width
,
"number"
)
||
!
isType
(
height
,
"number"
)
||
width
<=
0
||
height
<=
0
)
{
if
(
!
utils
.
isType
(
width
,
"number"
)
||
!
utils
.
isType
(
height
,
"number"
)
||
width
<=
0
||
height
<=
0
)
{
throw
new
Error
(
"Invalid viewport width/height set: "
+
width
+
'x'
+
height
);
}
this
.
page
.
viewportSize
=
{
...
...
@@ -910,10 +907,10 @@ Casper.prototype = {
*/
wait
:
function
(
timeout
,
then
)
{
timeout
=
Number
(
timeout
,
10
);
if
(
!
isType
(
timeout
,
"number"
)
||
timeout
<
1
)
{
if
(
!
utils
.
isType
(
timeout
,
"number"
)
||
timeout
<
1
)
{
this
.
die
(
"wait() only accepts a positive integer > 0 as a timeout value"
);
}
if
(
then
&&
!
isType
(
then
,
"function"
))
{
if
(
then
&&
!
utils
.
isType
(
then
,
"function"
))
{
this
.
die
(
"wait() a step definition must be a function"
);
}
return
this
.
then
(
function
(
self
)
{
...
...
@@ -947,10 +944,10 @@ Casper.prototype = {
*/
waitFor
:
function
(
testFx
,
then
,
onTimeout
,
timeout
)
{
timeout
=
timeout
?
timeout
:
this
.
defaultWaitTimeout
;
if
(
!
isType
(
testFx
,
"function"
))
{
if
(
!
utils
.
isType
(
testFx
,
"function"
))
{
this
.
die
(
"waitFor() needs a test function"
);
}
if
(
then
&&
!
isType
(
then
,
"function"
))
{
if
(
then
&&
!
utils
.
isType
(
then
,
"function"
))
{
this
.
die
(
"waitFor() next step definition must be a function"
);
}
return
this
.
then
(
function
(
self
)
{
...
...
@@ -964,7 +961,7 @@ Casper.prototype = {
self
.
waitDone
();
if
(
!
condition
)
{
self
.
log
(
"Casper.waitFor() timeout"
,
"warning"
);
if
(
isType
(
onTimeout
,
"function"
))
{
if
(
utils
.
isType
(
onTimeout
,
"function"
))
{
onTimeout
.
call
(
self
,
self
);
}
else
{
self
.
die
(
"Timeout of "
+
timeout
+
"ms expired, exiting."
,
"error"
);
...
...
@@ -1073,8 +1070,109 @@ Casper.prototype = {
* @param Object proto Prototype methods to add to Casper
*/
Casper
.
extend
=
function
(
proto
)
{
if
(
!
isType
(
proto
,
"object"
))
{
if
(
!
utils
.
isType
(
proto
,
"object"
))
{
throw
new
Error
(
"extends() only accept objects as prototypes"
);
}
mergeObjects
(
Casper
.
prototype
,
proto
);
};
exports
.
Casper
=
Casper
;
/**
* Creates a new WebPage instance for Casper use.
*
* @param Casper casper A Casper instance
* @return WebPage
*/
function
createPage
(
casper
)
{
var
page
;
if
(
phantom
.
version
.
major
<=
1
&&
phantom
.
version
.
minor
<
3
&&
utils
.
isType
(
require
,
"function"
))
{
page
=
new
WebPage
();
}
else
{
page
=
require
(
'webpage'
).
create
();
}
page
.
onAlert
=
function
(
message
)
{
casper
.
log
(
'[alert] '
+
message
,
"info"
,
"remote"
);
if
(
utils
.
isType
(
casper
.
options
.
onAlert
,
"function"
))
{
casper
.
options
.
onAlert
.
call
(
casper
,
casper
,
message
);
}
};
page
.
onConsoleMessage
=
function
(
msg
)
{
var
level
=
"info"
,
test
=
/^
\[
casper:
(\w
+
)\]\s?(
.*
)
/
.
exec
(
msg
);
if
(
test
&&
test
.
length
===
3
)
{
level
=
test
[
1
];
msg
=
test
[
2
];
}
casper
.
log
(
msg
,
level
,
"remote"
);
};
page
.
onLoadStarted
=
function
()
{
casper
.
resources
=
[];
casper
.
loadInProgress
=
true
;
};
page
.
onLoadFinished
=
function
(
status
)
{
if
(
status
!==
"success"
)
{
var
message
=
'Loading resource failed with status='
+
status
;
if
(
casper
.
currentHTTPStatus
)
{
message
+=
' (HTTP '
+
casper
.
currentHTTPStatus
+
')'
;
}
message
+=
': '
+
casper
.
requestUrl
;
casper
.
log
(
message
,
"warning"
);
if
(
utils
.
isType
(
casper
.
options
.
onLoadError
,
"function"
))
{
casper
.
options
.
onLoadError
.
call
(
casper
,
casper
,
casper
.
requestUrl
,
status
);
}
}
if
(
casper
.
options
.
clientScripts
)
{
if
(
betterTypeOf
(
casper
.
options
.
clientScripts
)
!==
"array"
)
{
casper
.
log
(
"The clientScripts option must be an array"
,
"error"
);
}
else
{
for
(
var
i
=
0
;
i
<
casper
.
options
.
clientScripts
.
length
;
i
++
)
{
var
script
=
casper
.
options
.
clientScripts
[
i
];
if
(
casper
.
page
.
injectJs
(
script
))
{
casper
.
log
(
'Automatically injected '
+
script
+
' client side'
,
"debug"
);
}
else
{
casper
.
log
(
'Failed injecting '
+
script
+
' client side'
,
"warning"
);
}
}
}
}
// Client-side utils injection
var
injected
=
page
.
evaluate
(
replaceFunctionPlaceholders
(
function
()
{
eval
(
"var ClientUtils = "
+
decodeURIComponent
(
"%utils%"
));
__utils__
=
new
ClientUtils
();
return
__utils__
instanceof
ClientUtils
;
},
{
utils
:
encodeURIComponent
(
require
(
'./lib/clientutils'
).
ClientUtils
.
toString
())
}));
if
(
!
injected
)
{
casper
.
log
(
"Failed to inject Casper client-side utilities!"
,
"warning"
);
}
else
{
casper
.
log
(
"Successfully injected Casper client-side utilities"
,
"debug"
);
}
// history
casper
.
history
.
push
(
casper
.
getCurrentUrl
());
casper
.
loadInProgress
=
false
;
};
page
.
onResourceReceived
=
function
(
resource
)
{
if
(
utils
.
isType
(
casper
.
options
.
onResourceReceived
,
"function"
))
{
casper
.
options
.
onResourceReceived
.
call
(
casper
,
casper
,
resource
);
}
if
(
resource
.
stage
===
"end"
)
{
casper
.
resources
.
push
(
resource
);
}
if
(
resource
.
url
===
casper
.
requestUrl
&&
resource
.
stage
===
"start"
)
{
casper
.
currentHTTPStatus
=
resource
.
status
;
if
(
utils
.
isType
(
casper
.
options
.
httpStatusHandlers
,
"object"
)
&&
resource
.
status
in
casper
.
options
.
httpStatusHandlers
&&
utils
.
isType
(
casper
.
options
.
httpStatusHandlers
[
resource
.
status
],
"function"
))
{
casper
.
options
.
httpStatusHandlers
[
resource
.
status
].
call
(
casper
,
casper
,
resource
);
}
casper
.
currentUrl
=
resource
.
url
;
}
};
page
.
onResourceRequested
=
function
(
request
)
{
if
(
utils
.
isType
(
casper
.
options
.
onResourceRequested
,
"function"
))
{
casper
.
options
.
onResourceRequested
.
call
(
casper
,
casper
,
request
);
}
};
return
page
;
}
...
...
lib/clientutils.js
View file @
301d634
...
...
@@ -26,14 +26,15 @@
*
*/
function
create
()
{
(
function
(
exports
)
{
exports
.
create
=
function
()
{
return
new
ClientUtils
();
}
};
/**
/**
* Casper client-side helpers.
*/
var
ClientUtils
=
function
()
{
var
ClientUtils
=
function
()
{
var
BASE64_ENCODE_CHARS
=
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
;
var
BASE64_DECODE_CHARS
=
new
Array
(
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
...
...
@@ -440,4 +441,5 @@ var ClientUtils = function() {
}
return
out
;
};
};
};
})(
exports
||
{});
...
...
lib/colorizer.js
View file @
301d634
...
...
@@ -26,12 +26,9 @@
*
*/
exports
.
create
=
create
;
exports
.
Colorizer
=
Colorizer
;
function
create
()
{
exports
.
create
=
function
()
{
return
new
Colorizer
();
}
}
;
/**
* This is a port of lime colorizer.
...
...
@@ -95,3 +92,4 @@ var Colorizer = function() {
return
"\033["
+
codes
.
join
(
';'
)
+
'm'
+
text
+
"\033[0m"
;
};
};
exports
.
Colorizer
=
Colorizer
;
...
...
lib/injector.js
View file @
301d634
...
...
@@ -27,15 +27,15 @@
*/
exports
.
create
=
create
;
exports
.
FunctionArgsInjector
=
FunctionArgsInjector
;
function
create
(
fn
)
{
exports
.
create
=
function
(
fn
)
{
return
new
FunctionArgsInjector
(
fn
);
}
}
;
/**
* Function argument injector.
*
* FIXME: use new Function() instead of eval()
*/
var
FunctionArgsInjector
=
function
(
fn
)
{
if
(
!
isType
(
fn
,
"function"
))
{
...
...
@@ -82,3 +82,4 @@ var FunctionArgsInjector = function(fn) {
return
inject
.
join
(
'\n'
)
+
'\n'
;
};
};
exports
.
FunctionArgsInjector
=
FunctionArgsInjector
;
...
...
lib/tester.js
View file @
301d634
...
...
@@ -27,10 +27,11 @@
*/
var
fs
=
require
(
'fs'
);
var
utils
=
require
(
'./lib/utils'
);
function
create
(
casper
,
options
)
{
exports
.
create
=
function
(
casper
,
options
)
{
return
new
Tester
(
casper
,
options
);
}
}
;
/**
* Casper tester: makes assertions, stores test results and display then.
...
...
@@ -39,9 +40,9 @@ function create(casper, options) {
var
Tester
=
function
(
casper
,
options
)
{
this
.
running
=
false
;
this
.
suites
=
[];
this
.
options
=
isType
(
options
,
"object"
)
?
options
:
{};
this
.
options
=
utils
.
isType
(
options
,
"object"
)
?
options
:
{};
if
(
!
casper
instanceof
require
(
'./lib/casper'
).
Casper
)
{
if
(
!
utils
.
isCasperObject
(
casper
)
)
{
throw
new
Error
(
"Tester needs a Casper instance"
);
}
...
...
@@ -219,7 +220,7 @@ var Tester = function(casper, options) {
* @param String message Test description
*/
this
.
assertType
=
function
(
input
,
type
,
message
)
{
return
this
.
assertEquals
(
betterTypeOf
(
input
),
type
,
message
);
return
this
.
assertEquals
(
utils
.
betterTypeOf
(
input
),
type
,
message
);
};
/**
...
...
@@ -368,7 +369,7 @@ var Tester = function(casper, options) {
* @param Boolean exit
*/
this
.
renderResults
=
function
(
exit
,
status
,
save
)
{
save
=
isType
(
save
,
"string"
)
?
save
:
this
.
options
.
save
;
save
=
utils
.
isType
(
save
,
"string"
)
?
save
:
this
.
options
.
save
;
var
total
=
this
.
testResults
.
passed
+
this
.
testResults
.
failed
,
statusText
,
style
,
result
;
if
(
this
.
testResults
.
failed
>
0
)
{
statusText
=
FAIL
;
...
...
@@ -379,7 +380,7 @@ var Tester = function(casper, options) {
}
result
=
statusText
+
' '
+
total
+
' tests executed, '
+
this
.
testResults
.
passed
+
' passed, '
+
this
.
testResults
.
failed
+
' failed.'
;
casper
.
echo
(
this
.
colorize
(
fillBlanks
(
result
),
style
));
if
(
save
&&
isType
(
require
,
"function"
))
{
if
(
save
&&
utils
.
isType
(
require
,
"function"
))
{
try
{
fs
.
write
(
save
,
exporter
.
getXML
(),
'w'
);
casper
.
echo
(
'result log stored in '
+
save
,
'INFO'
);
...
...
@@ -455,10 +456,10 @@ var Tester = function(casper, options) {
* @param Boolean
*/
this
.
testEquals
=
function
(
v1
,
v2
)
{
if
(
betterTypeOf
(
v1
)
!==
betterTypeOf
(
v2
))
{
if
(
utils
.
betterTypeOf
(
v1
)
!==
utils
.
betterTypeOf
(
v2
))
{
return
false
;
}
if
(
isType
(
v1
,
"function"
))
{
if
(
utils
.
isType
(
v1
,
"function"
))
{
return
v1
.
toString
()
===
v2
.
toString
();
}
if
(
v1
instanceof
Object
&&
v2
instanceof
Object
)
{
...
...
@@ -475,3 +476,4 @@ var Tester = function(casper, options) {
return
v1
===
v2
;
};
};
exports
.
Tester
=
Tester
;
...
...
lib/utils.js
View file @
301d634
...
...
@@ -41,105 +41,7 @@ function betterTypeOf(input) {
return
typeof
input
;
}
}
/**
* Creates a new WebPage instance for Casper use.
*
* @param Casper casper A Casper instance
* @return WebPage
*/
function
createPage
(
casper
)
{
var
page
;
if
(
phantom
.
version
.
major
<=
1
&&
phantom
.
version
.
minor
<
3
&&
isType
(
require
,
"function"
))
{
page
=
new
WebPage
();
}
else
{
page
=
require
(
'webpage'
).
create
();
}
page
.
onAlert
=
function
(
message
)
{
casper
.
log
(
'[alert] '
+
message
,
"info"
,
"remote"
);
if
(
isType
(
casper
.
options
.
onAlert
,
"function"
))
{
casper
.
options
.
onAlert
.
call
(
casper
,
casper
,
message
);
}
};
page
.
onConsoleMessage
=
function
(
msg
)
{
var
level
=
"info"
,
test
=
/^
\[
casper:
(\w
+
)\]\s?(
.*
)
/
.
exec
(
msg
);
if
(
test
&&
test
.
length
===
3
)
{
level
=
test
[
1
];
msg
=
test
[
2
];
}
casper
.
log
(
msg
,
level
,
"remote"
);
};
page
.
onLoadStarted
=
function
()
{
casper
.
resources
=
[];
casper
.
loadInProgress
=
true
;
};
page
.
onLoadFinished
=
function
(
status
)
{
if
(
status
!==
"success"
)
{
var
message
=
'Loading resource failed with status='
+
status
;
if
(
casper
.
currentHTTPStatus
)
{
message
+=
' (HTTP '
+
casper
.
currentHTTPStatus
+
')'
;
}
message
+=
': '
+
casper
.
requestUrl
;
casper
.
log
(
message
,
"warning"
);
if
(
isType
(
casper
.
options
.
onLoadError
,
"function"
))
{
casper
.
options
.
onLoadError
.
call
(
casper
,
casper
,
casper
.
requestUrl
,
status
);
}
}
if
(
casper
.
options
.
clientScripts
)
{
if
(
betterTypeOf
(
casper
.
options
.
clientScripts
)
!==
"array"
)
{
casper
.
log
(
"The clientScripts option must be an array"
,
"error"
);
}
else
{
for
(
var
i
=
0
;
i
<
casper
.
options
.
clientScripts
.
length
;
i
++
)
{
var
script
=
casper
.
options
.
clientScripts
[
i
];
if
(
casper
.
page
.
injectJs
(
script
))
{
casper
.
log
(
'Automatically injected '
+
script
+
' client side'
,
"debug"
);
}
else
{
casper
.
log
(
'Failed injecting '
+
script
+
' client side'
,
"warning"
);
}
}
}
}
// Client-side utils injection
var
injected
=
page
.
evaluate
(
replaceFunctionPlaceholders
(
function
()
{
eval
(
"var ClientUtils = "
+
decodeURIComponent
(
"%utils%"
));
__utils__
=
new
ClientUtils
();
return
__utils__
instanceof
ClientUtils
;
},
{
utils
:
encodeURIComponent
(
require
(
'./lib/clientutils'
).
ClientUtils
.
toString
())
}));
if
(
!
injected
)
{
casper
.
log
(
"Failed to inject Casper client-side utilities!"
,
"warning"
);
}
else
{
casper
.
log
(
"Successfully injected Casper client-side utilities"
,
"debug"
);
}
// history
casper
.
history
.
push
(
casper
.
getCurrentUrl
());
casper
.
loadInProgress
=
false
;
};
page
.
onResourceReceived
=
function
(
resource
)
{
if
(
isType
(
casper
.
options
.
onResourceReceived
,
"function"
))
{
casper
.
options
.
onResourceReceived
.
call
(
casper
,
casper
,
resource
);
}
if
(
resource
.
stage
===
"end"
)
{
casper
.
resources
.
push
(
resource
);
}
if
(
resource
.
url
===
casper
.
requestUrl
&&
resource
.
stage
===
"start"
)
{
casper
.
currentHTTPStatus
=
resource
.
status
;
if
(
isType
(
casper
.
options
.
httpStatusHandlers
,
"object"
)
&&
resource
.
status
in
casper
.
options
.
httpStatusHandlers
&&
isType
(
casper
.
options
.
httpStatusHandlers
[
resource
.
status
],
"function"
))
{
casper
.
options
.
httpStatusHandlers
[
resource
.
status
].
call
(
casper
,
casper
,
resource
);
}
casper
.
currentUrl
=
resource
.
url
;
}
};
page
.
onResourceRequested
=
function
(
request
)
{
if
(
isType
(
casper
.
options
.
onResourceRequested
,
"function"
))
{
casper
.
options
.
onResourceRequested
.
call
(
casper
,
casper
,
request
);
}
};
return
page
;
}
exports
.
betterTypeOf
=
betterTypeOf
;
/**
* Dumps a JSON representation of passed value to the console. Used for
...
...
@@ -150,6 +52,7 @@ function createPage(casper) {
function
dump
(
value
)
{
console
.
log
(
serialize
(
value
));
}
exports
.
dump
=
dump
;
/**
* Returns the file extension in lower case.
...
...
@@ -164,6 +67,7 @@ function fileExt(file) {
return
''
;
}
}
exports
.
fileExt
=
fileExt
;
/**
* Takes a string and append blank until the pad value is reached.
...
...
@@ -179,6 +83,18 @@ function fillBlanks(text, pad) {
}
return
text
;
}
exports
.
fillBlanks
=
fillBlanks
;
/**
* Checks if passed argument is an instance of Capser object.
*
* @param mixed value
* @return Boolean
*/
function
isCasperObject
(
value
)
{
return
value
instanceof
require
(
'./lib/casper'
).
Casper
;
}
exports
.
isCasperObject
=
isCasperObject
;
/**
* Checks if a file is apparently javascript compatible (.js or .coffee).
...
...
@@ -190,6 +106,7 @@ function isJsFile(file) {
var
ext
=
fileExt
(
file
);
return
isType
(
ext
,
"string"
)
&&
[
'js'
,
'coffee'
].
indexOf
(
ext
)
!==
-
1
;
}
exports
.
isJsFile
=
isJsFile
;
/**
* Shorthands for checking if a value is of the given type. Can check for
...
...
@@ -202,6 +119,7 @@ function isJsFile(file) {
function
isType
(
what
,
typeName
)
{
return
betterTypeOf
(
what
)
===
typeName
;
}
exports
.
isType
=
isType
;
/**
* Checks if the provided var is a WebPage instance
...
...
@@ -219,6 +137,7 @@ function isWebPage(what) {
return
what
.
toString
().
indexOf
(
'WebPage('
)
===
0
;
}
}
exports
.
isWebPage
=
isWebPage
;
/**
* Object recursive merging utility.
...
...
@@ -241,6 +160,7 @@ function mergeObjects(obj1, obj2) {
}
return
obj1
;
}
exports
.
mergeObjects
=
mergeObjects
;
/**
* Replaces a function string contents with placeholders provided by an
...
...
@@ -262,6 +182,7 @@ function replaceFunctionPlaceholders(fn, replacements) {
}
return
fn
;
}
exports
.
replaceFunctionPlaceholders
=
replaceFunctionPlaceholders
;
/**
* Serializes a value using JSON.
...
...
@@ -277,3 +198,4 @@ function serialize(value) {
}
return
JSON
.
stringify
(
value
,
null
,
4
);
}
exports
.
serialize
=
serialize
;
...
...
lib/xunit.js
View file @
301d634
...
...
@@ -26,12 +26,9 @@
*
*/
exports
.
create
=
create
;
exports
.
XUnitExporter
=
XUnitExporter
;
function
create
()
{
exports
.
create
=
function
()
{
return
new
XUnitExporter
();
}
}
;
/**
* JUnit XML (xUnit) exporter for test results.
...
...
@@ -97,3 +94,5 @@ XUnitExporter = function() {
return
xml
;
};
};
exports
.
XUnitExporter
=
XUnitExporter
;
...
...
Please
register
or
sign in
to post a comment