Commit 80669cda 80669cdab302946f8300af5d28c8719b3d0719d1 by Nicolas Perriault

added Casper#getCurrentUrl() & onLoadError callback option + tests

1 parent f8160f0d
......@@ -33,6 +33,7 @@
* logLevel | String | "error" | Logging level (see logLevels for available values)
* onDie | function | null | A function to be called when Casper#die() is called
* onError | function | null | A function to be called when an "error" level event occurs
* onLoadError | function | null | A function to be called when a requested resource cannot be loaded
* onPageInitialized | function | null | A function to be called after WebPage instance has been initialized
* page | WebPage | null | An existing WebPage instance
* pageSettings | Object | {} | PhantomJS's WebPage settings object
......@@ -56,6 +57,7 @@
logLevel: "error",
onDie: null,
onError: null,
onLoadError: null,
onPageInitialized: null,
page: null,
pageSettings: { userAgent: DEFAULT_USER_AGENT },
......@@ -64,6 +66,7 @@
};
// local properties
this.checker = null;
this.currentUrl = 'about:blank';
this.currentHTTPStatus = 200;
this.loadInProgress = false;
this.logLevels = ["debug", "info", "warning", "error"];
......@@ -358,6 +361,17 @@
},
/**
* Retrieve current document url.
*
* @return String
*/
getCurrentUrl: function() {
return decodeURIComponent(this.evaluate(function() {
return document.location.href;
}));
},
/**
* Logs a message.
*
* @param String message The message to log
......@@ -568,14 +582,8 @@
* @return Boolean
*/
this.click = function(selector) {
try {
var elem = document.querySelector(selector);
} catch (e) {
console.log('invalid selector: ' + selector);
return false;
}
var elem = document.querySelector(selector);
if (!elem) {
console.log('selector "' + selector + '" did not find any matching element');
return false;
}
var evt = document.createEvent("MouseEvents");
......@@ -694,6 +702,34 @@
};
/**
* Finds all DOM elements matching by the provided selector.
*
* @param String selector CSS3 selector
* @return NodeList|undefined
*/
this.findAll = function(selector) {
try {
return document.querySelectorAll(selector);
} catch (e) {
console.log('findAll(): invalid selector provided "' + selector + '":' + e);
}
};
/**
* Finds a DOM element by the provided selector.
*
* @param String selector CSS3 selector
* @return HTMLElement|undefined
*/
this.findOne = function(selector) {
try {
return document.querySelector(selector);
} catch (e) {
console.log('findOne(): invalid selector provided "' + selector + '":' + e);
}
};
/**
* Downloads a resource behind an url and returns its base64-encoded
* contents.
*
......@@ -822,6 +858,9 @@
}
message += ': ' + casper.requestUrl;
casper.log(message, "warning");
if (typeof(casper.options.onLoadError) === "function") {
casper.options.onLoadError(casper, casper.requestUrl, status);
}
}
if (casper.options.clientScripts) {
for (var i = 0; i < casper.options.clientScripts.length; i++) {
......@@ -842,15 +881,16 @@
utils: encodeURIComponent(phantom.Casper.ClientUtils.toString())
}));
if (!injected) {
casper.log('Failed to inject Casper client-side utilities!', "warning");
casper.log("Failed to inject Casper client-side utilities!", "warning");
} else {
casper.log('Successfully injected Casper client-side utilities', "debug");
casper.log("Successfully injected Casper client-side utilities", "debug");
}
casper.loadInProgress = false;
};
page.onResourceReceived = function(resource) {
if (resource.url === casper.requestUrl) {
casper.currentHTTPStatus = resource.status;
casper.currentUrl = resource.url;
}
};
return page;
......
......@@ -35,6 +35,20 @@ phantom.Casper.extend({
return this.assertEquals(this.evaluate(fn), expected, message);
},
assertMatch: function(subject, pattern, message) {
return this.assert(pattern.test(subject), message);
},
assertTitle: function(expected, message) {
return this.assertEvalEquals(function() {
return document.title;
}, expected, message);
},
assertUrlMatch: function(pattern, message) {
return this.assertMatch(this.getCurrentUrl(), pattern, message);
},
renderResults: function() {
this.echo("==========================================");
var total = testResults.passed + testResults.failed,
......
......@@ -26,9 +26,7 @@ casper.options.verbose = true;
// Casper#start()
casper.start('tests/site/index.html', function(self) {
self.assertEvalEquals(function() {
return document.title;
}, 'CasperJS test index', 'start() casper can start itself an open an url');
self.assertTitle('CasperJS test index', 'start() casper can start itself an open an url');
self.assertEval(function() {
return typeof(__utils__) === "object";
}, 'start() injects ClientUtils instance within remote DOM');
......@@ -41,9 +39,7 @@ casper.assert(casper.steps.length === 1, 'start() can add a new navigation step'
// Casper#then()
casper.then(function(self) {
self.assertEvalEquals(function() {
return document.title;
}, 'CasperJS test target', 'click() casper can click on a text link and react when it is loaded 1/2');
self.assertTitle('CasperJS test target', 'click() casper can click on a text link and react when it is loaded 1/2');
self.click('a[href="form.html"]');
});
......@@ -51,14 +47,13 @@ casper.assert(casper.steps.length === 2, 'then() adds a new navigation step');
// Casper#fill()
casper.then(function(self) {
self.assertEvalEquals(function() {
return document.title;
}, 'CasperJS test form', 'click() casper can click on a text link and react when it is loaded 2/2');
self.fill('form[action="form.html"]', {
self.assertTitle('CasperJS test form', 'click() casper can click on a text link and react when it is loaded 2/2');
self.fill('form[action="result.html"]', {
email: 'chuck@norris.com',
content: 'Am watching thou',
check: true,
choice: 'no',
topic: 'bar',
file: phantom.libraryPath + '/README.md'
});
self.assertEvalEquals(function() {
......@@ -68,6 +63,9 @@ casper.then(function(self) {
return document.querySelector('textarea[name="content"]').value;
}, 'Am watching thou', 'fill() can fill a textarea form field');
self.assertEvalEquals(function() {
return document.querySelector('select[name="topic"]').value;
}, 'bar', 'fill() can pick a value from a select form field');
self.assertEvalEquals(function() {
return document.querySelector('input[name="check"]').checked;
}, true, 'fill() can check a form checkbox');
self.assertEvalEquals(function() {
......@@ -79,9 +77,17 @@ casper.then(function(self) {
self.assertEvalEquals(function() {
return document.querySelector('input[name="file"]').files.length === 1;
}, true, 'fill() can select a file to upload');
self.evaluate(function() {
document.querySelector('form[action="form.html"]').submit();
})
self.click('input[type="submit"]');
});
// Casper#click()
casper.then(function(self) {
self.assertTitle('CasperJS test form result', 'click() casper can click on a submit button');
self.assertUrlMatch(/email=chuck@norris.com/, 'fill() input[type=email] field was submitted');
self.assertUrlMatch(/content=Am\+watching\+thou/, 'fill() textarea field was submitted');
self.assertUrlMatch(/check=on/, 'fill() input[type=checkbox] field was submitted');
self.assertUrlMatch(/choice=no/, 'fill() input[type=radio] field was submitted');
self.assertUrlMatch(/topic=bar/, 'fill() select field was submitted');
});
casper.run(function(self) {
......
......@@ -5,7 +5,7 @@
<title>CasperJS test form</title>
</head>
<body>
<form action="form.html" enctype="multipart/form-data">
<form action="result.html" enctype="multipart/form-data">
<input type="text" name="email" placeholder="email" />
<textarea name="content"></textarea>
<select name="topic">
......