diff --git a/vendor/casperjs/.gitattributes b/vendor/casperjs/.gitattributes new file mode 100755 index 0000000..176a458 --- /dev/null +++ b/vendor/casperjs/.gitattributes @@ -0,0 +1 @@ +* text=auto diff --git a/vendor/casperjs/.gitignore b/vendor/casperjs/.gitignore new file mode 100755 index 0000000..eecc4e2 --- /dev/null +++ b/vendor/casperjs/.gitignore @@ -0,0 +1,8 @@ +.DS_Store +/*.xml +/*.png +/docs/*.js +/docs/*.xml +/docs/_build +/tmp +*.pyc diff --git a/vendor/casperjs/.gitmodules b/vendor/casperjs/.gitmodules new file mode 100755 index 0000000..e69de29 diff --git a/vendor/casperjs/.jshintignore b/vendor/casperjs/.jshintignore new file mode 100755 index 0000000..cc2233b --- /dev/null +++ b/vendor/casperjs/.jshintignore @@ -0,0 +1,11 @@ +docs +modules/vendors +modules/events.js +modules/querystring.js +samples/** +tests/clitests/** +tests/testdir/** +tmp +./*.js +./phantomjs*/* +./engine/* diff --git a/vendor/casperjs/.jshintrc b/vendor/casperjs/.jshintrc new file mode 100755 index 0000000..4533c38 --- /dev/null +++ b/vendor/casperjs/.jshintrc @@ -0,0 +1,25 @@ +{ + "asi": true, + "browser": true, + "debug": true, + "devel": true, + "eqeqeq": true, + "evil": true, + "maxparams": 5, + "maxdepth": 3, + "maxstatements": 15, + "maxcomplexity": 7, + "proto": true, + "regexdash": true, + "strict": true, + "sub": true, + "trailing": true, + "undef": true, + + "predef" : [ + "exports", + "phantom", + "window", + "require" + ] +} diff --git a/vendor/casperjs/.travis.yml b/vendor/casperjs/.travis.yml new file mode 100755 index 0000000..14097d9 --- /dev/null +++ b/vendor/casperjs/.travis.yml @@ -0,0 +1,60 @@ +branches: + only: + - "master" + +before_install: + - echo "Installing $ENGINE $ENGINE_VERSION from $ENGINE_ARCHIVE_URL" + - wget $ENGINE_ARCHIVE_URL --output-document=engine.tar.bz2 + - mkdir engine && tar --strip-components=1 -xvf engine.tar.bz2 -C engine + - if [[ $ENGINE == 'phantomjs' ]]; then + ENGINE_EXECUTABLE="engine/bin/phantomjs"; + elif [[ $ENGINE == 'slimerjs' ]]; then + ENGINE_EXECUTABLE="engine/slimerjs"; + else + echo "Unsupported engine $ENGINE"; + fi + - ls -la $ENGINE_EXECUTABLE && $ENGINE_EXECUTABLE --version; + - export ENGINE_EXECUTABLE="$ENGINE_EXECUTABLE $ENGINE_FLAGS" + +install: + - sudo apt-get install -qq mono-devel mono-mcs + +before_script: + - "npm install -g jshint@2.0.1" + +script: + - "make $MAKE_TEST_COMMAND" + +env: + global: + - ENGINE_FLAGS="--local-to-remote-url-access=yes --ignore-ssl-errors=yes" + matrix: + - ENGINE="phantomjs" ENGINE_VERSION="1.8.2" MAKE_TEST_COMMAND="test-dotNET" + ENGINE_ARCHIVE_URL="https://phantomjs.googlecode.com/files/phantomjs-1.8.2-linux-x86_64.tar.bz2" + - ENGINE="phantomjs" ENGINE_VERSION="1.8.2" MAKE_TEST_COMMAND="test" + ENGINE_ARCHIVE_URL="https://phantomjs.googlecode.com/files/phantomjs-1.8.2-linux-x86_64.tar.bz2" + - ENGINE="phantomjs" ENGINE_VERSION="1.9.0" MAKE_TEST_COMMAND="test-dotNET" + ENGINE_ARCHIVE_URL="https://phantomjs.googlecode.com/files/phantomjs-1.9.0-linux-x86_64.tar.bz2" + - ENGINE="phantomjs" ENGINE_VERSION="1.9.0" MAKE_TEST_COMMAND="test" + ENGINE_ARCHIVE_URL="https://phantomjs.googlecode.com/files/phantomjs-1.9.0-linux-x86_64.tar.bz2" + - ENGINE="phantomjs" ENGINE_VERSION="1.9.1" MAKE_TEST_COMMAND="test-dotNET" + ENGINE_ARCHIVE_URL="https://phantomjs.googlecode.com/files/phantomjs-1.9.1-linux-x86_64.tar.bz2" + - ENGINE="phantomjs" ENGINE_VERSION="1.9.1" MAKE_TEST_COMMAND="test" + ENGINE_ARCHIVE_URL="https://phantomjs.googlecode.com/files/phantomjs-1.9.1-linux-x86_64.tar.bz2" + - ENGINE="phantomjs" ENGINE_VERSION="1.9.2" MAKE_TEST_COMMAND="test-dotNET" + ENGINE_ARCHIVE_URL="https://phantomjs.googlecode.com/files/phantomjs-1.9.2-linux-x86_64.tar.bz2" + - ENGINE="phantomjs" ENGINE_VERSION="1.9.2" MAKE_TEST_COMMAND="test" + ENGINE_ARCHIVE_URL="https://phantomjs.googlecode.com/files/phantomjs-1.9.2-linux-x86_64.tar.bz2" + - ENGINE="slimerjs" ENGINE_VERSION="0.8.4" MAKE_TEST_COMMAND="test-dotNET" + ENGINE_ARCHIVE_URL="http://download.slimerjs.org/v0.8/0.8.4/slimerjs-0.8.4-linux-x86_64.tar.bz2" + - ENGINE="slimerjs" ENGINE_VERSION="0.8.4" MAKE_TEST_COMMAND="test" + ENGINE_ARCHIVE_URL="http://download.slimerjs.org/v0.8/0.8.4/slimerjs-0.8.4-linux-x86_64.tar.bz2" + - ENGINE="slimerjs" ENGINE_VERSION="0.8.5" MAKE_TEST_COMMAND="test-dotNET" + ENGINE_ARCHIVE_URL="http://download.slimerjs.org/v0.8/0.8.5/slimerjs-0.8.5-linux-x86_64.tar.bz2" + - ENGINE="slimerjs" ENGINE_VERSION="0.8.5" MAKE_TEST_COMMAND="test" + ENGINE_ARCHIVE_URL="http://download.slimerjs.org/v0.8/0.8.5/slimerjs-0.8.5-linux-x86_64.tar.bz2" + +notifications: + irc: + channels: + - "irc.freenode.org#casperjs" diff --git a/vendor/casperjs/CHANGELOG.md b/vendor/casperjs/CHANGELOG.md new file mode 100755 index 0000000..92f799c --- /dev/null +++ b/vendor/casperjs/CHANGELOG.md @@ -0,0 +1 @@ +[This file has moved to Github](https://github.com/n1k0/casperjs/releases) diff --git a/vendor/casperjs/CONTRIBUTING.md b/vendor/casperjs/CONTRIBUTING.md new file mode 100755 index 0000000..e92e404 --- /dev/null +++ b/vendor/casperjs/CONTRIBUTING.md @@ -0,0 +1,93 @@ +# Contribution Guide + +*Note: this guide has been heavily inspired by [PhantomJS' one](https://github.com/ariya/phantomjs/blob/master/CONTRIBUTING.md).* + +**This page describes how to contribute changes to the [CasperJS](http://casperjs.org/) project.** + +Please do **not** create a pull request without reading this guide first. Failure to do so may result in the **rejection** of the pull request. + +## For The Impatients + +**Work on a feature branch**. +If your changes need to be modified due to some reviews, it is less clutter to tweak an isolated feature branch and push it again. + +**Create a ticket in the [issue tracker](https://github.com/n1k0/casperjs/issues/)**. +This serves as a placeholder for important feedback, review, or any future updates. **Please ensure searching the bugtracker for an already opened issue matching your case before filing a new issue.** + +In the commit message(s): + +* **Keep the first line short**. Write additional paragraphs if necessary. +* **Reference an opened issue**, by referencing the issue ID prefixed by a `#` and the keyword `refs`, eg. `refs #123` + +Sample commit message: + +> refs #123 - fixed error message formatting +> +> (optional: a short explanation of what the patch actually does) + +**Run tests** + +Run CasperJS' test suite to see you didn't break something: + + $ casperjs selftest + +The result status bar **must be green** before sending your PR. + +## Communicate + +**Improvement and feature request**. If you have an improvement idea, please send an email to the [mailing list](http://groups.google.com/group/casperjs) (preferable than contacting the developers directly) so that other people can give their insights and opinions. This is also important to avoid duplicate work. + +**Help request**. If you're stuck using CasperJS and don't understand how to achieve something, please [ask on the mailing-list](https://groups.google.com/forum/#!forum/casperjs) first. Please don't ask for all the kind people to write your scripts for you. + +**Ensure the issue is related to CasperJS**. Please try to reproduce the issue using plain PhantomJS. If it works with the native PhantomJS API but doesn't with CasperJS, then the issue is probably valid. In the opposite case, please file an issue on [PhantomJS issue tracker](http://code.google.com/p/phantomjs/issues/list). + +**Extending with new API**. Whenever you want to introduce a new API, please send an email to the mailing list along with the link to the issue if any. It may require few iterations to agree on the final API and hence it is important to engage all interested parties as early as possible. + +## Get Ready + +### Use Feature Branch + +To isolate your change, please avoid working on the master branch. Instead, work on a *feature branch* (often also known as *topic branch*). You can create a new branch (example here crash-fix) off the master branch by using: + + git checkout -b crash-fix master + +Refer to your favorite Git tutorial/book for further detailed help. + +Some good practices for the feature branch: + +* Give it a meaningful name instead of, e.g. `prevent-zero-divide` instead of just `fix` +* Make *granular* and *atomic* commits, e.g. do not mix a typo fix with some major refactoring +* Keep one branch for one specific issue. If you need to work on other unrelated issues, create another branch. + +### Write tests + +CasperJS being partly a testing framework, how irrelevant would be to send a pull request with no test? So, please take the time to write and attach tests to your PR. Furthermore, testing with CasperJS is quite [exhaustively documented](http://casperjs.org/testing.html). + +### Run tests! + +This may sound obvious but **don't send pull requests which break the casperjs test suite**. + +To see if your modifications broke the suite, just run: + + $ casperjs selftest + +### Write documentation + +Do you appreciate the [CasperJS documentation](http://casperjs.org/)? I do too. As the documentation contents are managed and generated using Github, Markdown and CasperJS itself, take the time to read the [Documentation Contribution Guide](https://github.com/n1k0/casperjs/blob/gh-pages/README.md#casperjs-documentation) and write the documentation related to your PR whenever applicable. + +**Note:** As the documentation is handled in a [dedicated separated `gh-pages` branch](https://github.com/n1k0/casperjs/tree/gh-pages), you'll have to send a dedicated PR for doc patches. I'm working on a more comfortable solution, but it's no easy task though. + +## Review and Merge + +When your branch is ready, send the pull request. + +While it is not always the case, often it is necessary to improve parts of your code in the branch. This is the actual review process. + +Here is a check list for the review: + +* It does not break the test suite +* There is no typo +* The coding style follows the existing one +* There is a reasonable amount of comment +* The license header is intact +* All examples are still working diff --git a/vendor/casperjs/CONTRIBUTORS.md b/vendor/casperjs/CONTRIBUTORS.md new file mode 100755 index 0000000..86c046e --- /dev/null +++ b/vendor/casperjs/CONTRIBUTORS.md @@ -0,0 +1,109 @@ +# CasperJS contributors + +You can check out the [contribution graphs on github](https://github.com/n1k0/casperjs/graphs/contributors). + +``` +$ git shortlog -s -n | cut -c8- +Nicolas Perriault +Mickaël Andrieu +Laurent Jouanneau +hexid +Brikou CARRE +oncletom +Matt DuVall +Nathan Black +hannyu +Julien Muetton +Chris Bosco +Matt Bowman +Shiryaev Andrey +mickaelandrieu +Clochix +Chris Lorenzo +Victor Yap +JF Paradis +Matthew DuVall +Rob Barreca +Oleg Pudeyev +pborreli +nrabinowitz +Darrell Hamilton +Tyler Ritchie +Andrew Childs +Eric Bouchut +Dave Lee +Solomon White +Luke Rodgers +reina.sweet +renatodarrigo +Donovan Hutchinson +Sean Massa +Vladimir Chizhov +Samuel Gabel +Reina Sweet +Jan Schaumann +fwebdev +Reid Lynch +Justin Collum +Philip Hansen +Michael Geers +Orchestrator81 +Nick Currier +Julien Moulin +Elmar Langholz +Jason Funk +Lee Byrd +Thomas Rosenau +V Sreekanth +Patrick Reagan +Andrew de Andrade +Andy Shinn +Ben Johnson +Ben Lowery +Bert Pareyn +Brandon Bethke +Charlie Park +Chris Winters +Christophe Benz +Dharrya +Dmitry Menshikov +Florent DUBOST +Harrison Reiser +Itamar Nabriski +Ivan +Jamey J. DeOrio +Jan Pochyla +Jan-Martin Fruehwacht +John F. Douthat +Julian Gruber +Justin Marsan +Justin Slattery +Justine Tunney +KaroDidi +Leandro Boscariol +Maisons du monde +Marcel Duran +Mathieu Agopian +Mehdi Kabab +Miguel González +Mikhail Korobov +Mikko Peltonen +Narno +Pascal Borreli +Phillip Alexander +Rafael +Rafael Garcia +Raphaël Benitte +Rock Li +Scott +Thomas Parisot +Tim Bunce +Tzvi Friedman +Yasuo Ohgaki +Yevgeny Smirnov +alfetopito +jayseeg +jean-philippe serafin +shekyan +snkashis +``` diff --git a/vendor/casperjs/LICENSE.md b/vendor/casperjs/LICENSE.md new file mode 100755 index 0000000..5c308cb --- /dev/null +++ b/vendor/casperjs/LICENSE.md @@ -0,0 +1,19 @@ +Copyright (c) 2011-2012 Nicolas Perriault + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/casperjs/Makefile b/vendor/casperjs/Makefile new file mode 100755 index 0000000..2e26ff0 --- /dev/null +++ b/vendor/casperjs/Makefile @@ -0,0 +1,25 @@ +.PHONY: default test test-dotNET docs selftest compile-dotNET selftest-dotNET clitest jshint + +default: test + +test: selftest clitest jshint + +test-dotNET: compile-dotNET selftest-dotNET + +docs: + sphinx-build -b html ./docs docs/_build + +selftest: + bin/casperjs selftest + +compile-dotNET: + mcs -langversion:3 -out:bin/casperjs.exe src/casperjs.cs + +selftest-dotNET: + bin/casperjs.exe selftest + +clitest: + python tests/clitests/runtests.py + +jshint: + jshint . diff --git a/vendor/casperjs/README.md b/vendor/casperjs/README.md new file mode 100755 index 0000000..f6c56e7 --- /dev/null +++ b/vendor/casperjs/README.md @@ -0,0 +1,94 @@ +# CasperJS + +>**Important note:** the `master` branch hosts the development version of CasperJS, which is now pretty stable and should be the right version to use if you ask me. +> +>Use the [`1.0` branch](https://github.com/n1k0/casperjs/tree/1.0) if you want to keep in sync with the stable old version, or [use tagged versions](https://github.com/n1k0/casperjs/tags). +> +>Currently, available documentation is: +> +>- **hosted on [docs.casperjs.org](http://docs.casperjs.org/) for the development branch** +>- hosted on [casperjs.org](http://casperjs.org/) for the 1.0 branch +> +>[Travis-CI](http://travis-ci.org/n1k0/casperjs) build status: +> +>- ![Build Status](https://travis-ci.org/n1k0/casperjs.png?branch=master) `master` branch +>- 1.0 tests unfortunately have to be run manually using the `casperjs selftest` command + +CasperJS is a navigation scripting & testing utility for [PhantomJS](http://www.phantomjs.org/) +and [SlimerJS](http://slimerjs.org/). It eases the process of defining a full navigation +scenario and provides useful high-level functions, methods & syntaxic sugar for doing common +tasks such as: + +- defining & ordering [navigation steps](http://docs.casperjs.org/en/latest/quickstart.html) +- [filling forms](http://docs.casperjs.org/en/latest/modules/casper.html#fill) +- [clicking links](http://docs.casperjs.org/en/latest/modules/casper.html#click) +- [capturing screenshots](http://docs.casperjs.org/en/latest/modules/casper.html#captureselector) of a page (or an area) +- [making assertions on remote DOM](http://docs.casperjs.org/en/latest/modules/tester.html) +- [logging](http://docs.casperjs.org/en/latest/logging.html) & [events](http://docs.casperjs.org/en/latest/events-filters.html) +- [downloading](http://docs.casperjs.org/en/latest/modules/casper.html#download) resources, even binary ones +- catching errors and react accordingly +- writing [functional test suites](http://docs.casperjs.org/en/latest/testing.html), exporting results as JUnit XML (xUnit) + +Browse the [sample examples repository](https://github.com/n1k0/casperjs/tree/master/samples). +Don't hesitate to pull request for any cool example of yours as well! + +**Read the [full documentation](http://docs.casperjs.org/) on casperjs documentation website.** + +Subscribe to the [project mailing-list](https://groups.google.com/forum/#!forum/casperjs) + +Follow the CasperJS project [on twitter](https://twitter.com/casperjs_org) and [Google+](https://plus.google.com/b/106641872690063476159/). + +## Show me some code! + +First [install CasperJS](http://docs.casperjs.org/en/latest/installation.html), we'll use 1.1 beta here. + +Sample test to see if some dropdown can be opened: + +```javascript +casper.test.begin('a twitter bootstrap dropdown can be opened', 2, function(test) { + casper.start('http://getbootstrap.com/2.3.2/javascript.html#dropdowns', function() { + test.assertExists('#navbar-example'); + this.click('#dropdowns .nav-pills .dropdown:last-of-type a.dropdown-toggle'); + this.waitUntilVisible('#dropdowns .nav-pills .open', function() { + test.pass('Dropdown is open'); + }); + }).run(function() { + test.done(); + }); +}); +``` + +Run the script: + +![](http://cl.ly/image/271e2i403A0F/Capture%20d%E2%80%99%C3%A9cran%202013-01-20%20%C3%A0%2009.26.15.png) + +##Support + +Need help with getting CasperJS up and running? Got a time-consuming problem you want to get solved quickly? + +Get CasperJS support on CodersClan. + + +## Contributing + +### Contributing code + +Please read the [CONTRIBUTING.md](https://github.com/n1k0/casperjs/blob/master/CONTRIBUTING.md) file contents. + +### Contributing documentation + +CasperJS's documentation is written using the [Markdown format](http://daringfireball.net/projects/markdown/), and hosted on Github thanks to the [Github Pages Feature](http://pages.github.com/). + +To view the source files on github, head to [the gh-pages branch](https://github.com/n1k0/casperjs/tree/gh-pages), and check the [documentation's README](https://github.com/n1k0/casperjs/tree/gh-pages#readme) for further instructions. + +## Team + +- Nicolas Perriault ([@n1k0](https://github.com/n1k0)) +- Nick Currier ([@hexid](https://github.com/hexid)) +- Laurent Jouanneau ([@laurentj](https://github.com/laurentj)) +- Mickaël Andrieu ([@mickaelandrieu](https://github.com/mickaelandrieu)) +- Matt DuVall ([@mduvall](https://github.com/mduvall)) + +## License + +MIT diff --git a/vendor/casperjs/batchbin/casperjs.bat b/vendor/casperjs/batchbin/casperjs.bat new file mode 100755 index 0000000..dd86a98 --- /dev/null +++ b/vendor/casperjs/batchbin/casperjs.bat @@ -0,0 +1,5 @@ +@ECHO OFF +set CASPER_PATH=%~dp0.. +set CASPER_BIN=%CASPER_PATH%\bin\ +set ARGV=%* +call phantomjs "%CASPER_BIN%bootstrap.js" --casper-path="%CASPER_PATH%" --cli %ARGV% \ No newline at end of file diff --git a/vendor/casperjs/bin/bootstrap.js b/vendor/casperjs/bin/bootstrap.js new file mode 100755 index 0000000..61d1b62 --- /dev/null +++ b/vendor/casperjs/bin/bootstrap.js @@ -0,0 +1,395 @@ +/*! + * Casper is a navigation utility for PhantomJS. + * + * Documentation: http://casperjs.org/ + * Repository: http://github.com/n1k0/casperjs + * + * Copyright (c) 2011-2012 Nicolas Perriault + * + * Part of source code is Copyright Joyent, Inc. and other Node contributors. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +/*global process, console, phantom, slimer, require:true*/ +/*jshint maxstatements:34, maxcomplexity:10*/ + +// node check +if ('process' in this && process.title === "node") { + console.error('CasperJS cannot be executed within a nodejs environment'); + process.exit(1); +} + +// phantom check +if (!('phantom' in this)) { + console.error('CasperJS needs to be executed in a PhantomJS environment http://phantomjs.org/'); +} + +// Common polyfills +if (typeof Function.prototype.bind !== "function") { + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind#Compatibility + Function.prototype.bind = function (oThis) { + "use strict"; + /* jshint -W055 */ + if (typeof this !== "function") { + // closest thing possible to the ECMAScript 5 internal IsCallable function + throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable"); + } + var aArgs = Array.prototype.slice.call(arguments, 1), + fToBind = this, + fNOP = function() {}, + fBound = function() { + return fToBind.apply(this instanceof fNOP && oThis ? this : oThis, + aArgs.concat(Array.prototype.slice.call(arguments))); + }; + fNOP.prototype = this.prototype; + fBound.prototype = new fNOP(); + return fBound; + }; +} + +// Custom base error +var CasperError = function CasperError(msg) { + "use strict"; + Error.call(this); + this.message = msg; + this.name = 'CasperError'; +}; +CasperError.prototype = Object.getPrototypeOf(new Error()); + +// casperjs env initialization +(function(global, phantom){ + "use strict"; + // phantom args + // NOTE: we can't use require('system').args here for some very obscure reason + // do not even attempt at using it as it creates infinite recursion + var phantomArgs = phantom.args; + + if (phantom.casperLoaded) { + return; + } + + function __die(message) { + if (message) { + console.error(message); + } + phantom.exit(1); + } + + function __terminate(message) { + if (message) { + console.log(message); + } + phantom.exit(); + } + + (function(version) { + // required version check + if (version.major !== 1) { + return __die('CasperJS needs PhantomJS v1.x'); + } if (version.minor < 8) { + return __die('CasperJS needs at least PhantomJS v1.8 or later.'); + } + if (version.minor === 8 && version.patch < 1) { + return __die('CasperJS needs at least PhantomJS v1.8.1 or later.'); + } + })(phantom.version); + + // Hooks in default phantomjs error handler + phantom.onError = function onPhantomError(msg, trace) { + phantom.defaultErrorHandler.apply(phantom, arguments); + // print a hint when a possible casperjs command misuse is detected + if (msg.indexOf("ReferenceError: Can't find variable: casper") === 0) { + console.error('Hint: you may want to use the `casperjs test` command.'); + } + // exits on syntax error + if (msg.indexOf('SyntaxError: Parse error') === 0) { + __die(); + } + }; + + // Patching fs + var fs = (function patchFs(fs) { + if (!fs.hasOwnProperty('basename')) { + fs.basename = function basename(path) { + return path.replace(/.*\//, ''); + }; + } + if (!fs.hasOwnProperty('dirname')) { + fs.dirname = function dirname(path) { + if (!path) return undefined; + return path.toString().replace(/\\/g, '/').replace(/\/[^\/]*$/, ''); + }; + } + if (!fs.hasOwnProperty('isWindows')) { + fs.isWindows = function isWindows() { + var testPath = arguments[0] || this.workingDirectory; + return (/^[a-z]{1,2}:/i).test(testPath) || testPath.indexOf("\\\\") === 0; + }; + } + if (fs.hasOwnProperty('joinPath')) { + fs.pathJoin = fs.joinPath; + } else if (!fs.hasOwnProperty('pathJoin')) { + fs.pathJoin = function pathJoin() { + return Array.prototype.join.call(arguments, '/'); + }; + } + return fs; + })(require('fs')); + + // CasperJS root path + if (!phantom.casperPath) { + try { + phantom.casperPath = phantom.args.map(function _map(arg) { + var match = arg.match(/^--casper-path=(.*)/); + if (match) { + return fs.absolute(match[1]); + } + }).filter(function _filter(path) { + return fs.isDirectory(path); + }).pop(); + } catch (e) { + return __die("Couldn't find nor compute phantom.casperPath, exiting."); + } + } + + /** + * Prints CasperJS help. + */ + function printHelp() { + var engine = phantom.casperEngine === 'slimerjs' ? slimer : phantom; + var version = [engine.version.major, engine.version.minor, engine.version.patch].join('.'); + return __terminate([ + 'CasperJS version ' + phantom.casperVersion.toString() + + ' at ' + phantom.casperPath + ', using ' + phantom.casperEngine + ' version ' + version, + fs.read(fs.pathJoin(phantom.casperPath, 'bin', 'usage.txt')) + ].join('\n')) + } + + /** + * Patched require to allow loading of native casperjs modules. + * Every casperjs module have to first call this function in order to + * load a native casperjs module: + * + * var require = patchRequire(require); + * var utils = require('utils'); + * + * Useless for SlimerJS + */ + function patchRequire(require) { + if (require.patched) { + return require; + } + function fromPackageJson(module, dir) { + var pkgPath, pkgContents, pkg; + pkgPath = fs.pathJoin(dir, module, 'package.json'); + if (!fs.exists(pkgPath)) { + return; + } + pkgContents = fs.read(pkgPath); + if (!pkgContents) { + return; + } + try { + pkg = JSON.parse(pkgContents); + } catch (e) { + return; + } + if (typeof pkg === "object" && pkg.main) { + return fs.absolute(fs.pathJoin(dir, module, pkg.main)); + } + } + function resolveFile(path, dir) { + var extensions = ['js', 'coffee', 'json']; + var basenames = [path, path + '/index']; + var paths = []; + var nodejsScript = fromPackageJson(path, dir); + if (nodejsScript) { + return nodejsScript; + } + basenames.forEach(function(basename) { + paths.push(fs.absolute(fs.pathJoin(dir, basename))); + extensions.forEach(function(extension) { + paths.push(fs.absolute(fs.pathJoin(dir, [basename, extension].join('.')))); + }); + }); + for (var i = 0; i < paths.length; i++) { + if (fs.isFile(paths[i])) { + return paths[i]; + } + } + return null; + } + function getCurrentScriptRoot() { + if ((phantom.casperScriptBaseDir || "").indexOf(fs.workingDirectory) === 0) { + return phantom.casperScriptBaseDir; + } + return fs.absolute(fs.pathJoin(fs.workingDirectory, phantom.casperScriptBaseDir)); + } + function casperBuiltinPath(path) { + return resolveFile(path, fs.pathJoin(phantom.casperPath, 'modules')); + } + function nodeModulePath(path) { + return resolveFile(path, fs.pathJoin(getCurrentScriptRoot(), 'node_modules')); + } + function localModulePath(path) { + return resolveFile(path, phantom.casperScriptBaseDir || fs.workingDirectory); + } + var patchedRequire = function patchedRequire(path) { + try { + return require(casperBuiltinPath(path) || + nodeModulePath(path) || + localModulePath(path) || + path); + } catch (e) { + throw new CasperError("Can't find module " + path); + } + }; + patchedRequire.cache = require.cache; + patchedRequire.extensions = require.extensions; + patchedRequire.stubs = require.stubs; + patchedRequire.patched = true; + return patchedRequire; + } + + /** + * Initializes the CasperJS Command Line Interface. + */ + function initCasperCli(casperArgs) { + /* jshint maxcomplexity:99 */ + var baseTestsPath = fs.pathJoin(phantom.casperPath, 'tests'); + + function setScriptBaseDir(scriptName) { + var dir = fs.dirname(scriptName); + if (dir === scriptName) { + dir = '.'; + } + phantom.casperScriptBaseDir = dir; + } + + if (!!casperArgs.options.version) { + return __terminate(phantom.casperVersion.toString()) + } else if (casperArgs.get(0) === "test") { + phantom.casperScript = fs.absolute(fs.pathJoin(baseTestsPath, 'run.js')); + phantom.casperTest = true; + casperArgs.drop("test"); + setScriptBaseDir(casperArgs.get(0)); + } else if (casperArgs.get(0) === "selftest") { + phantom.casperScript = fs.absolute(fs.pathJoin(baseTestsPath, 'run.js')); + phantom.casperSelfTest = phantom.casperTest = true; + casperArgs.options.includes = fs.pathJoin(baseTestsPath, 'selftest.js'); + if (casperArgs.args.length <= 1) { + casperArgs.args.push(fs.pathJoin(baseTestsPath, 'suites')); + } + casperArgs.drop("selftest"); + phantom.casperScriptBaseDir = fs.dirname(casperArgs.get(1) || fs.dirname(phantom.casperScript)); + } else if (casperArgs.args.length === 0 || !!casperArgs.options.help) { + return printHelp(); + } + + if (!phantom.casperScript) { + phantom.casperScript = casperArgs.get(0); + } + + if (phantom.casperScript !== "/dev/stdin" && !fs.isFile(phantom.casperScript)) { + return __die('Unable to open file: ' + phantom.casperScript); + } + + if (!phantom.casperScriptBaseDir) { + setScriptBaseDir(phantom.casperScript); + } + + // filter out the called script name from casper args + casperArgs.drop(phantom.casperScript); + } + + // CasperJS version, extracted from package.json - see http://semver.org/ + phantom.casperVersion = (function getCasperVersion(path) { + var parts, patchPart, pkg, pkgFile; + pkgFile = fs.absolute(fs.pathJoin(path, 'package.json')); + if (!fs.exists(pkgFile)) { + throw new CasperError('Cannot find package.json at ' + pkgFile); + } + try { + pkg = JSON.parse(require('fs').read(pkgFile)); + } catch (e) { + throw new CasperError('Cannot read package file contents: ' + e); + } + parts = pkg.version.trim().split("."); + if (parts.length < 3) { + throw new CasperError("Invalid version number"); + } + patchPart = parts[2].split('-'); + return { + major: ~~parts[0] || 0, + minor: ~~parts[1] || 0, + patch: ~~patchPart[0] || 0, + ident: patchPart[1] || "", + toString: function toString() { + var version = [this.major, this.minor, this.patch].join('.'); + if (this.ident) { + version = [version, this.ident].join('-'); + } + return version; + } + }; + })(phantom.casperPath); + + if ("slimer" in global) { + // for SlimerJS, use the standard API to declare directories + // where to search modules + require.paths.push(fs.pathJoin(phantom.casperPath, 'modules')); + require.paths.push(fs.workingDirectory); + + // declare a dummy patchRequire function + require.globals.patchRequire = global.patchRequire = function(req) { return req;}; + require.globals.CasperError = CasperError; + phantom.casperEngine = "slimerjs"; + } + else { + // patch require + global.__require = require; + global.patchRequire = patchRequire; // must be called in every casperjs module as of 1.1 + global.require = patchRequire(global.require); + phantom.casperEngine = "phantomjs"; + } + + // casper cli args + phantom.casperArgs = require('cli').parse(phantomArgs); + + if (true === phantom.casperArgs.get('cli')) { + initCasperCli(phantom.casperArgs); + } + + if ("slimer" in global && phantom.casperScriptBaseDir) { + // initCasperCli has set casperScriptBaseDir + // use it instead of fs.workingDirectory + require.paths.pop(); + require.paths.push(phantom.casperScriptBaseDir); + } + + // casper loading status flag + phantom.casperLoaded = true; + + // passed casperjs script execution + if (phantom.casperScript && !phantom.injectJs(phantom.casperScript)) { + return __die('Unable to load script ' + phantom.casperScript + '; check file syntax'); + } +})(this, phantom); diff --git a/vendor/casperjs/bin/casperjs b/vendor/casperjs/bin/casperjs new file mode 100755 index 0000000..d0e3031 --- /dev/null +++ b/vendor/casperjs/bin/casperjs @@ -0,0 +1,140 @@ +#!/usr/bin/env python + +import os +import sys + +def resolve(path): + if os.path.islink(path): + path = os.path.join(os.path.dirname(path), os.readlink(path)) + return resolve(path) + return path + +SUPPORTED_ENGINES = { + 'phantomjs' : { + 'native_args': [ + 'cookies-file', + 'config', + 'debug', + 'disk-cache', + 'ignore-ssl-errors', + 'load-images', + 'load-plugins', + 'local-storage-path', + 'local-storage-quota', + 'local-to-remote-url-access', + 'max-disk-cache-size', + 'output-encoding', + 'proxy', + 'proxy-auth', + 'proxy-type', + 'remote-debugger-port', + 'remote-debugger-autorun', + 'script-encoding', + 'ssl-protocol', + 'ssl-certificates-path', + 'web-security', + 'webdriver', + 'webdriver-logfile', + 'webdriver-loglevel' + 'webdriver-selenium-grid-hub', + 'wd', + 'w', + ], + 'env_varname': 'PHANTOMJS_EXECUTABLE', + 'default_exec' : 'phantomjs' + }, + 'slimerjs': { + 'native_args': [ + 'P', + 'jsconsole', + 'CreateProfile', + 'profile', + #phantomjs options + 'cookies-file', + 'config', + 'debug', + 'disk-cache', + 'ignore-ssl-errors', + 'load-images', + 'load-plugins', + 'local-storage-path', + 'local-storage-quota', + 'local-to-remote-url-access', + 'max-disk-cache-size', + 'output-encoding', + 'proxy', + 'proxy-auth', + 'proxy-type', + 'remote-debugger-port', + 'remote-debugger-autorun', + 'script-encoding', + 'ssl-protocol', + 'ssl-certificates-path', + 'web-security', + 'webdriver', + 'webdriver-logfile', + 'webdriver-loglevel' + 'webdriver-selenium-grid-hub', + 'wd', + 'w', + ], + 'env_varname': 'SLIMERJS_EXECUTABLE', + 'default_exec' : 'slimerjs' + }, +} + +ENGINE = 'phantomjs' +ENGINE_ARGS = [] +ENGINE_NATIVE_ARGS = [] +ENGINE_EXECUTABLE = '' + +CASPER_ARGS = [] +CASPER_PATH = os.path.abspath(os.path.join(os.path.dirname(resolve(__file__)), + '..')) +SYS_ARGS = sys.argv[1:] + +# retrieve the engine name +for arg in SYS_ARGS: + if arg.startswith('--engine='): + ENGINE = arg[9:].lower() + break + +if not ENGINE in SUPPORTED_ENGINES: + print('Bad engine name. Only phantomjs and slimerjs are supported') + sys.exit(1) + +ENGINE_NATIVE_ARGS = SUPPORTED_ENGINES[ENGINE]['native_args'] +ENGINE_EXECUTABLE = os.environ.get(SUPPORTED_ENGINES[ENGINE]['env_varname'], + SUPPORTED_ENGINES[ENGINE]['default_exec']) + +def extract_arg_name(arg): + "parse out any option name" + try: + return arg.split('=', 1)[0].replace('--', '', 1) + except IndexError: + return arg + +for arg in SYS_ARGS: + arg_name = extract_arg_name(arg) + found = False + for native in ENGINE_NATIVE_ARGS: + if arg_name == native: + ENGINE_ARGS.append(arg) + found = True + if not found and arg_name != 'engine': + CASPER_ARGS.append(arg) + +CASPER_COMMAND = ENGINE_EXECUTABLE.split(' ') +CASPER_COMMAND.extend(ENGINE_ARGS) +CASPER_COMMAND.extend([ + os.path.join(CASPER_PATH, 'bin', 'bootstrap.js'), + '--casper-path=%s' % CASPER_PATH, + '--cli' +]) +CASPER_COMMAND.extend(CASPER_ARGS) + +try: + os.execvp(CASPER_COMMAND[0], CASPER_COMMAND) +except OSError as err: + print('Fatal: %s; did you install %s?' % (err, ENGINE)) + sys.exit(1) diff --git a/vendor/casperjs/bin/casperjs.exe b/vendor/casperjs/bin/casperjs.exe new file mode 100755 index 0000000..4adeee3 Binary files /dev/null and b/vendor/casperjs/bin/casperjs.exe differ diff --git a/vendor/casperjs/bin/usage.txt b/vendor/casperjs/bin/usage.txt new file mode 100755 index 0000000..fed5e89 --- /dev/null +++ b/vendor/casperjs/bin/usage.txt @@ -0,0 +1,14 @@ +Usage: casperjs [options] script.[js|coffee] [script argument [script argument ...]] + casperjs [options] test [test path [test path ...]] + casperjs [options] selftest + casperjs [options] __selfcommandtest + +Options: + +--verbose Prints log messages to the console +--log-level Sets logging level +--help Prints this help +--version Prints out CasperJS version +--engine=name Use the given engine. Current supported engine: phantomjs and slimerjs + +Read the docs http://docs.casperjs.org/ diff --git a/vendor/casperjs/casperjs.gemspec b/vendor/casperjs/casperjs.gemspec new file mode 100755 index 0000000..abe051e --- /dev/null +++ b/vendor/casperjs/casperjs.gemspec @@ -0,0 +1,23 @@ +# by hannyu + +CASPERJS_VERSION = File.read("package.json")[/version.*:.*"(.*?)"/,1].gsub(/[\-_\+]/,".") + +Gem::Specification.new do |s| + s.name = "casperjs" + s.version = CASPERJS_VERSION + s.homepage = "http://casperjs.org/" + s.authors = ["Nicolas Perriault", ] + s.email = ["nperriault@gmail.com",] + s.description = "CasperJS is a navigation scripting & testing utility for [PhantomJS](http://www.phantomjs.org/). +It eases the process of defining a full navigation scenario and provides useful +high-level functions, methods & syntaxic sugar for doing common tasks." + s.summary = "Navigation scripting & testing utility for PhantomJS" + s.extra_rdoc_files = ["LICENSE.md", "README.md"] + s.files = Dir["LICENSE.md", "README.md", "CHANGELOG.md", "package.json", "casperjs.gemspec", + "bin/bootstrap.js", "bin/usage.txt", "bin/casperjs_python", + "docs/**/*", "modules/**/*", "samples/**/*", "tests/**/*"] + s.bindir = "rubybin" + s.executables = [ "casperjs" ] + s.license = "MIT" + s.requirements = [ "PhantomJS v1.7" ] +end diff --git a/vendor/casperjs/docs/Makefile b/vendor/casperjs/docs/Makefile new file mode 100755 index 0000000..3689ca3 --- /dev/null +++ b/vendor/casperjs/docs/Makefile @@ -0,0 +1,13 @@ +.PHONY: all default + +default: all + +all: build open + +build: + sphinx-build . _build + +open: + open _build/index.html + + diff --git a/vendor/casperjs/docs/README.md b/vendor/casperjs/docs/README.md new file mode 100755 index 0000000..6006018 --- /dev/null +++ b/vendor/casperjs/docs/README.md @@ -0,0 +1,5 @@ +CasperJS Sphinx Documentation +============================= + +Sphinx documentation for [CasperJS](http://casperjs.org/) 1.1-DEV and future +versions. Work in progress. diff --git a/vendor/casperjs/docs/_static/casperjs-favicon.ico b/vendor/casperjs/docs/_static/casperjs-favicon.ico new file mode 100755 index 0000000..eea7a6e Binary files /dev/null and b/vendor/casperjs/docs/_static/casperjs-favicon.ico differ diff --git a/vendor/casperjs/docs/_static/images/bg.png b/vendor/casperjs/docs/_static/images/bg.png new file mode 100755 index 0000000..6b37e86 Binary files /dev/null and b/vendor/casperjs/docs/_static/images/bg.png differ diff --git a/vendor/casperjs/docs/_static/images/casperjs-logo-medium.png b/vendor/casperjs/docs/_static/images/casperjs-logo-medium.png new file mode 100755 index 0000000..a30e4b0 Binary files /dev/null and b/vendor/casperjs/docs/_static/images/casperjs-logo-medium.png differ diff --git a/vendor/casperjs/docs/_static/images/casperjs-logo-small.png b/vendor/casperjs/docs/_static/images/casperjs-logo-small.png new file mode 100755 index 0000000..1e36b5c Binary files /dev/null and b/vendor/casperjs/docs/_static/images/casperjs-logo-small.png differ diff --git a/vendor/casperjs/docs/_static/images/casperjs-logo-squared-inv.png b/vendor/casperjs/docs/_static/images/casperjs-logo-squared-inv.png new file mode 100755 index 0000000..a0f4e6d Binary files /dev/null and b/vendor/casperjs/docs/_static/images/casperjs-logo-squared-inv.png differ diff --git a/vendor/casperjs/docs/_static/images/casperjs-logo-squared.png b/vendor/casperjs/docs/_static/images/casperjs-logo-squared.png new file mode 100755 index 0000000..f0768d5 Binary files /dev/null and b/vendor/casperjs/docs/_static/images/casperjs-logo-squared.png differ diff --git a/vendor/casperjs/docs/_static/images/casperjs-logo-xsmall.png b/vendor/casperjs/docs/_static/images/casperjs-logo-xsmall.png new file mode 100755 index 0000000..0ffda48 Binary files /dev/null and b/vendor/casperjs/docs/_static/images/casperjs-logo-xsmall.png differ diff --git a/vendor/casperjs/docs/_static/images/casperjs-logo.png b/vendor/casperjs/docs/_static/images/casperjs-logo.png new file mode 100755 index 0000000..421dd8e Binary files /dev/null and b/vendor/casperjs/docs/_static/images/casperjs-logo.png differ diff --git a/vendor/casperjs/docs/_static/images/casperjs-rounded.png b/vendor/casperjs/docs/_static/images/casperjs-rounded.png new file mode 100755 index 0000000..de8807e Binary files /dev/null and b/vendor/casperjs/docs/_static/images/casperjs-rounded.png differ diff --git a/vendor/casperjs/docs/_static/images/colorizer.png b/vendor/casperjs/docs/_static/images/colorizer.png new file mode 100755 index 0000000..def5b3c Binary files /dev/null and b/vendor/casperjs/docs/_static/images/colorizer.png differ diff --git a/vendor/casperjs/docs/_static/images/cow-test-ko.png b/vendor/casperjs/docs/_static/images/cow-test-ko.png new file mode 100755 index 0000000..a9ee71b Binary files /dev/null and b/vendor/casperjs/docs/_static/images/cow-test-ko.png differ diff --git a/vendor/casperjs/docs/_static/images/cow-test-ok.png b/vendor/casperjs/docs/_static/images/cow-test-ok.png new file mode 100755 index 0000000..09eaf9f Binary files /dev/null and b/vendor/casperjs/docs/_static/images/cow-test-ok.png differ diff --git a/vendor/casperjs/docs/_static/images/demo.png b/vendor/casperjs/docs/_static/images/demo.png new file mode 100755 index 0000000..a7b544a Binary files /dev/null and b/vendor/casperjs/docs/_static/images/demo.png differ diff --git a/vendor/casperjs/docs/_static/images/evaluate-diagram.png b/vendor/casperjs/docs/_static/images/evaluate-diagram.png new file mode 100755 index 0000000..aad59ea Binary files /dev/null and b/vendor/casperjs/docs/_static/images/evaluate-diagram.png differ diff --git a/vendor/casperjs/docs/_static/images/forkme.png b/vendor/casperjs/docs/_static/images/forkme.png new file mode 100755 index 0000000..d48529c Binary files /dev/null and b/vendor/casperjs/docs/_static/images/forkme.png differ diff --git a/vendor/casperjs/docs/_static/images/logoutput.png b/vendor/casperjs/docs/_static/images/logoutput.png new file mode 100755 index 0000000..2e61d81 Binary files /dev/null and b/vendor/casperjs/docs/_static/images/logoutput.png differ diff --git a/vendor/casperjs/docs/_static/images/split-test-results.png b/vendor/casperjs/docs/_static/images/split-test-results.png new file mode 100755 index 0000000..ae6c108 Binary files /dev/null and b/vendor/casperjs/docs/_static/images/split-test-results.png differ diff --git a/vendor/casperjs/docs/_static/images/tar.png b/vendor/casperjs/docs/_static/images/tar.png new file mode 100755 index 0000000..343b53f Binary files /dev/null and b/vendor/casperjs/docs/_static/images/tar.png differ diff --git a/vendor/casperjs/docs/_static/images/testsuiteok.png b/vendor/casperjs/docs/_static/images/testsuiteok.png new file mode 100755 index 0000000..dde3081 Binary files /dev/null and b/vendor/casperjs/docs/_static/images/testsuiteok.png differ diff --git a/vendor/casperjs/docs/_static/images/zip.png b/vendor/casperjs/docs/_static/images/zip.png new file mode 100755 index 0000000..2099c7c Binary files /dev/null and b/vendor/casperjs/docs/_static/images/zip.png differ diff --git a/vendor/casperjs/docs/_themes/casperjs/addon.html b/vendor/casperjs/docs/_themes/casperjs/addon.html new file mode 100755 index 0000000..a6238a1 --- /dev/null +++ b/vendor/casperjs/docs/_themes/casperjs/addon.html @@ -0,0 +1,15 @@ +

Donate

+ diff --git a/vendor/casperjs/docs/_themes/casperjs/layout.html b/vendor/casperjs/docs/_themes/casperjs/layout.html new file mode 100755 index 0000000..23c6623 --- /dev/null +++ b/vendor/casperjs/docs/_themes/casperjs/layout.html @@ -0,0 +1,7 @@ +{%- extends "basic/layout.html" %} +{% block extrahead %} + + + + +{% endblock extrahead %} diff --git a/vendor/casperjs/docs/_themes/casperjs/localtoc.html b/vendor/casperjs/docs/_themes/casperjs/localtoc.html new file mode 100755 index 0000000..ea535a6 --- /dev/null +++ b/vendor/casperjs/docs/_themes/casperjs/localtoc.html @@ -0,0 +1,4 @@ +{%- if display_toc %} +

{{ _('Document Outline') }}

+ {{ toc }} +{%- endif %} diff --git a/vendor/casperjs/docs/_themes/casperjs/sourcelink.html b/vendor/casperjs/docs/_themes/casperjs/sourcelink.html new file mode 100755 index 0000000..223d8ab --- /dev/null +++ b/vendor/casperjs/docs/_themes/casperjs/sourcelink.html @@ -0,0 +1,16 @@ +

Index

+

Thesaurus

+ +{%- if show_source and has_source and sourcename %} +

{{ _('This Page') }}

+ +{%- endif %} diff --git a/vendor/casperjs/docs/_themes/casperjs/static/casperjs-dark.css b/vendor/casperjs/docs/_themes/casperjs/static/casperjs-dark.css new file mode 100755 index 0000000..ebc9552 --- /dev/null +++ b/vendor/casperjs/docs/_themes/casperjs/static/casperjs-dark.css @@ -0,0 +1,991 @@ +/** + * casper.css + * ~~~~~~~~~~~~~~~ + * + * CasperJS stylesheet, based on RTD one: + * + * Sphinx stylesheet -- sphinxdoc theme. Originally created by + * Armin Ronacher for Werkzeug. + * + * Customized for ReadTheDocs by Eric Pierce & Eric Holscher + * + * :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +@import url("basic.css"); + +/* PAGE LAYOUT -------------------------------------------------------------- */ + +body { + font: 100%/1.5 Asap, "ff-meta-web-pro-1", "ff-meta-web-pro-2", Arial, "Helvetica Neue", sans-serif; + text-align: center; + color: #fff; + background-color: #222; + padding: 0; + margin: 0; +} + +img { + border: 0; + max-width: 100%; +} + +.body > .admonition.note { + margin: 0 0 2em 0; +} + .body > .admonition.note .first { + display: none; + } + +div.document { + text-align: left; + background-color: #333; +} + +div.bodywrapper { + background: #111 url(images/bg.png); + border-left: 1px solid #333; + border-bottom: 1px solid #333; + margin: 0 18em 0 0; +} + +div.body { + margin: 0; + padding: 0.5em 1.3em; + min-width: 20em; +} + +div.related { + font-size: 1em; + background-color: #465158; +} + +div.documentwrapper { + float: left; + width: 100%; + background-color: #333; +} + + +/* HEADINGS --------------------------------------------------------------- */ + +h1 { + margin: 0; + padding: 0 0 0.3em 0; + font-size: 2em; + line-height: 1.15; + color: #fff; + clear: both; +} + +h2 { + margin: 2em 0 0.2em 0; + font-size: 1.35em; + padding: 0; + color: #fff; +} + .section h2 { + border-bottom: 3px solid #777; + margin-top: 2.5em + } + +h3 { + margin: 1em 0 -0.3em 0; + font-size: 1.2em; + color: #fff; +} + +div.body h1 a, div.body h2 a, div.body h3 a, div.body h4 a, div.body h5 a, div.body h6 a { + color: #fff; +} + +h1 a.anchor, h2 a.anchor, h3 a.anchor, h4 a.anchor, h5 a.anchor, h6 a.anchor { + display: none; + margin: 0 0 0 0.3em; + padding: 0 0.2em 0 0.2em; + color: #333 !important; +} + +h1:hover a.anchor, h2:hover a.anchor, h3:hover a.anchor, h4:hover a.anchor, +h5:hover a.anchor, h6:hover a.anchor { + display: inline; +} + +h1 a.anchor:hover, h2 a.anchor:hover, h3 a.anchor:hover, h4 a.anchor:hover, +h5 a.anchor:hover, h6 a.anchor:hover { + color: #777; + background-color: #eee; +} + + +/* LINKS ------------------------------------------------------------------ */ + +/* Normal links get a pseudo-underline */ +a { + color: #0bc; + text-decoration: none; +} +a.reference, a.internal { + color: #abf; +} + +a.reference em, a.internal em { + font-style: normal; +} + +/* Links in sidebar, TOC, index trees and tables have no underline */ +.sphinxsidebar a, +.toctree-wrapper a, +.indextable a, +#indices-and-tables a { + color: #0bc; + text-decoration: none; + border-bottom: none; +} + +/* Most links get an underline-effect when hovered */ +a:hover, +div.toctree-wrapper a:hover, +.indextable a:hover, +#indices-and-tables a:hover { + color: #2be; + text-decoration: none; +} + +/*toctree dedicated styles*/ +div.toctree-wrapper ul { + list-style-type: none; + padding-left: 2em; +} + +div.toctree-wrapper ul ul { + margin-top: .5em; +} + +div.toctree-wrapper li { + margin-bottom: .5em; +} + div.toctree-wrapper a, .toctree-wrapper a:visited { + padding: .2em .4em; + background-color: #555; + color:#fff; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + } + div.toctree-wrapper a:hover { + color: #eee; + background-color: #777; + } + +/* Footer links */ +div.footer a { + color: #0bc; + text-decoration: none; + border: none; +} +div.footer a:hover { + color: #2be; + border: none; +} + +/* Permalink anchor (subtle grey with a red hover) */ +div.body a.headerlink { + color: #ccc; + font-size: 1em; + margin-left: 6px; + padding: 0 4px 0 4px; + text-decoration: none; + border: none; +} +div.body a.headerlink:hover { + color: #fff; + border: none; +} + + +/* NAVIGATION BAR --------------------------------------------------------- */ + +div.related ul { + height: 2.5em; + min-height: 2.5em; + background-color: #2c2c2c; + background-image: -moz-linear-gradient(top, #333333, #222222); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#333333), to(#222222)); + background-image: -webkit-linear-gradient(top, #333333, #222222); + background-image: -o-linear-gradient(top, #333333, #222222); + background-image: linear-gradient(to bottom, #333333, #222222); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff333333', endColorstr='#ff222222', GradientType=0); + border-bottom: 1px solid #222; + -moz-border-radius: 4px; + -webkit-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.065); + -moz-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.065); + box-shadow: 0 1px 4px rgba(0, 0, 0, 0.065); + *zoom: 1; +} + +div.related ul li { + margin: 0; + padding: 0.65em 0; + float: left; + display: block; + color: white; /* For the >> separators */ + font-size: 0.8em; +} + +div.related ul li.right { + float: right; + margin-right: 5px; + color: transparent; /* Hide the | separators */ +} + +/* "Breadcrumb" links in nav bar */ +div.related ul li a { + order: none; + background-color: inherit; + font-weight: bold; + margin: 6px 0 6px 4px; + line-height: 1.75em; + color: #ffffff; + padding: 0.4em 0.8em; + border: none; + border-radius: 3px; +} +/* previous / next / modules / index links look more like buttons */ +div.related ul li.right a { + margin: 0.375em 0; + background-color: #555; + text-shadow: 0 1px rgba(0, 0, 0, 0.5); + border-radius: 3px; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; +} +/* All navbar links light up as buttons when hovered */ +div.related ul li a:hover { + background-color: #777; + color: #fff; + text-decoration: none; + border-radius: 3px; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; +} +/* Take extra precautions for tt within links */ +a tt, +div.related ul li a tt { + background: inherit !important; + color: inherit !important; +} + +.sphinxsidebar a tt span.pre { + color: #eee; + background-color: #444; + padding: 0 .5em; + border-radius: 4px; +} + +.sphinxsidebar a:active tt span.pre { + color: #f66; +} + + +/* SIDEBAR ---------------------------------------------------------------- */ + +div.sphinxsidebarwrapper { + padding: 0; +} + +div.sphinxsidebar { + margin: 0; + margin-left: -100%; + float: right; + top: 3em; + left: 0; + padding: 0 1em; + width: 18em; + font-size: 90%; + +} + +div.sphinxsidebar img { + max-width: 12em; +} + +div.sphinxsidebar input[type="image"] { + display: inline; + float: none; + border: 0; +} + +div.sphinxsidebar h3, +div.sphinxsidebar h4, +div.sphinxsidebar p.logo { + margin: 1.2em 0 0.3em 0; + font-size: 1em; + padding: 0; + color: #fff; + font-family: Asap, Arial, "ff-meta-web-pro-1", "ff-meta-web-pro-2", "Arial", "Helvetica Neue", sans-serif; +} + +div.sphinxsidebar h3 a { + color: #fff; +} + +div.sphinxsidebar ul, +div.sphinxsidebar p { + margin-top: 0; + padding-left: 0; + line-height: 130%; + +} + +/* No bullets for nested lists, but a little extra indentation */ +div.sphinxsidebar ul ul { + list-style-type: none; + margin-left: 1.2em; + padding: 0; +} + +/* A little top/bottom padding to prevent adjacent links' borders + * from overlapping each other */ +div.sphinxsidebar ul li { + padding: 0; + margin: 2px 0; +} + +/* A little left-padding to make these align with the ULs */ +div.sphinxsidebar p.topless { + padding-left: 0 0 0 1em; +} + +/* Make these into hidden one-liners */ +div.sphinxsidebar ul li, +div.sphinxsidebar p.topless { + white-space: nowrap; + overflow: hidden; + border: 1px solid transparent; /* To prevent things jumping around on hover */ +} +/* ...which become visible when hovered */ +div.sphinxsidebar ul li:hover, +div.sphinxsidebar p.topless:hover { + background-color: #333; + overflow: visible; + + +} + +/* Search text box and "Go" button */ +#searchbox { + margin-top: 2em; + margin-bottom: 1em; + background: #666; + padding: 0.5em; + border-radius: 6px; + -moz-border-radius: 6px; + -webkit-border-radius: 6px; + margin-right: 0; +} +#searchbox h3 { + margin-top: 0; +} + +/* Make search box and button abut and have a border */ +input, +div.sphinxsidebar input { + border: 1px solid #999; + float: left; +} + +/* Search textbox */ +input[type="text"] { + margin: 0; + padding: 0 3px; + height: 20px; + width: 144px; + border-top-left-radius: 3px; + border-bottom-left-radius: 3px; + -moz-border-radius-topleft: 3px; + -moz-border-radius-bottomleft: 3px; + -webkit-border-top-left-radius: 3px; + -webkit-border-bottom-left-radius: 3px; +} +/* Search button */ +input[type="submit"] { + margin: 0 0 0 -1px; /* -1px prevents a double-border with textbox */ + height: 22px; + color: #444; + background-color: #e8ecef; + padding: 1px 4px; + font-weight: bold; + border-top-right-radius: 3px; + border-bottom-right-radius: 3px; + -moz-border-radius-topright: 3px; + -moz-border-radius-bottomright: 3px; + -webkit-border-top-right-radius: 3px; + -webkit-border-bottom-right-radius: 3px; +} +input[type="submit"]:hover { + color: #000; + background-color: #ddd; +} + +div.sphinxsidebar p.searchtip { + clear: both; + padding: 0.5em 0 0 0; + color: #fff; + font-size: 0.9em; +} + +/* Sidebar links are unusual */ +div.sphinxsidebar li a, +div.sphinxsidebar p a { + color: #eee; + border-radius: 3px; + -moz-border-radius: 3px; + -webkit-border-radius: 3px; + border: 1px solid transparent; /* To prevent things jumping around on hover */ + padding: 0 5px 0 5px; +} +div.sphinxsidebar li a:hover, +div.sphinxsidebar p a:hover { + color: #fff; + background-color: #333; +} +div.sphinxsidebar p.logo a { + border: 0; +} + +/* Tweak any link appearing in a heading */ +div.sphinxsidebar h3 a { +} + + +/* OTHER STUFF ------------------------------------------------------------ */ + +/* labels */ +.versionmodified { + font-style: normal; +} + +.bookmarklet, .versionadded, .versionchanged { + display: inline-block; + padding: 4px 6px; + font-size: 13.536px; + font-weight: bold; + line-height: 14px; + color: #ffffff; + vertical-align: baseline; + white-space: nowrap; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #999999; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; + text-align: center; + font-style: normal; +} + .bookmarklet a, .versionadded a, .versionchanged a { + color: #fff; + } + +.bookmarklet { + background-color: #2d6987; +} + +.versionadded { + background-color: #468847; +} + div.admonition p.versionadded, + div.warning p.versionadded { + padding: 4px 6px; + } + +.versionchanged { + background-color: #b04040; +} + div.admonition p.versionchanged, + div.warning p.versionchanged { + padding: 4px 6px; + } + +/* Standard tags */ +cite, code, tt { + font-family: 'Source Code Pro', 'Consolas', 'Deja Vu Sans Mono', + 'Bitstream Vera Sans Mono', monospace; + font-size: 0.95em; + letter-spacing: 0.01em; +} + +tt { + color: #f66; + background-color: #444; + padding: 0 5px; + font-size: 95%; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} + +h1 tt, h2 tt, h3 tt, h4 tt, h5 tt { + padding: 0; + background: none; +} + +tt.descname, tt.descclassname, tt.xref { + border: 0; +} + +hr { + border-top: 1px solid #777; + border-bottom: none; + margin: 2em auto; + width: 50%; +} + + +pre, #_fontwidthtest { + font-family: 'Source Code Pro', 'Consolas', 'Deja Vu Sans Mono', + 'Bitstream Vera Sans Mono', monospace; + margin: 1em 2em; + font-size: 0.95em; + letter-spacing: 0.015em; + line-height: 120%; + padding: 0.5em; + border: 1px solid #ccc; + background-color: #eee; + border-radius: 6px; + -moz-border-radius: 6px; + -webkit-border-radius: 6px; +} + +pre a { + color: inherit; + text-decoration: underline; +} + +td.linenos pre { + margin: 1em 0em; +} + +td.code pre { + margin: 1em 0em; +} + +div.quotebar { + background-color: #f8f8f8; + max-width: 250px; + float: right; + padding: 2px 7px; + border: 1px solid #ccc; +} + +div.topic { + background-color: #333; + border: 0; + padding-bottom: .5em; + border-radius: 4px; + -moz-border-radius: 4px; + -webkit-border-radius: 4px; +} + +table { + border-collapse: collapse; + margin: 0 -0.5em 0 -0.5em; +} + +table td, table th { + padding: 0.2em 0.5em 0.2em 0.5em; +} + + +/* ADMONITIONS AND WARNINGS ------------------------------------------------- */ + +/* Shared by admonitions, warnings and sidebars */ +div.admonition, +div.warning, +div.sidebar { + font-size: 0.9em; + margin: 2em; + padding: 0; + /* + border-radius: 6px; + -moz-border-radius: 6px; + -webkit-border-radius: 6px; + */ +} +div.admonition p, +div.warning p, +div.sidebar p { + margin: 0.5em 1em 0.5em 1em; + padding: 0; +} +div.admonition pre, +div.warning pre, +div.sidebar pre { + margin: 0.4em 1em 0.4em 1em; +} +div.admonition p.admonition-title, +div.warning p.admonition-title, +div.sidebar p.sidebar-title { + margin: 0; + padding: 0.1em 0 0.1em 0.5em; + color: white; + font-weight: bold; + font-size: 1.1em; + text-shadow: 0 1px rgba(0, 0, 0, 0.5); +} +div.admonition ul, div.admonition ol, +div.warning ul, div.warning ol, +div.sidebar ul, div.sidebar ol { + margin: 0.1em 0.5em 0.5em 3em; + padding: 0; +} + + +/* Admonitions and sidebars only */ +div.admonition, div.sidebar { + border: none; + background-color: #555; + color: #fff; + padding: .5em; + margin-bottom: 1em; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + +} +div.admonition p.admonition-title, +div.sidebar p.sidebar-title { + padding-bottom: .5em; + border-bottom: 1px solid #888; +} + + +/* Warnings only */ +div.warning { + background-color: #333; +} +div.warning p.admonition-title { + background-color: #b04040; + border-bottom: 1px solid #900000; + border-radius: 4px; +} + + +/* Sidebars only */ +div.sidebar { + max-width: 30%; +} + + + +div.versioninfo { + margin: 1em 0 0 0; + border: 1px solid #ccc; + background-color: #DDEAF0; + padding: 8px; + line-height: 1.3em; + font-size: 0.9em; +} + +.viewcode-back { + font-family: Asap, 'Lucida Grande', 'Lucida Sans Unicode', 'Geneva', + 'Verdana', sans-serif; +} + +div.viewcode-block:target { + background-color: #f4debf; + border-top: 1px solid #ac9; + border-bottom: 1px solid #ac9; +} + +dl { + margin: 1em 0 2.5em 0; +} + +/* Highlight target when you click an internal link */ +dt:target { + background: #ffe080; +} +/* Don't highlight whole divs */ +div.highlight { + background: transparent; +} + div.highlight pre, + div.highlight-javascript pre, + div.highlight-html pre { + background-color: #4b4b4b; + background-color: rgba(75, 75, 75, 0.5); + color: #eee; + font-size: 15px; + line-height: 21px; + white-space: pre; + overflow: auto; + border: none; + } + div.admonition pre { + background-color: #333; + } + +/* But do highlight spans (so search results can be highlighted) */ +span.highlight { + background: #111; +} + +div.highlight .c1 { + color: #999; +} +div.highlight .cp { + color: #3aC; +} + +div.highlight .s, +div.highlight .s1, +div.highlight .s2 { + color: orange; +} + +div.highlight .kc { + color: red; +} +div.highlight .k, +div.highlight .kd { + color: #3aC; +} + +div.highlight .nb { + color: #e88; +} +div.highlight .nx { + color: #fff; +} + +div.highlight .p { + color: #eee; +} + +div.footer { + color: #eeeeee; + padding: 1em 2em 1em 2em; + clear: both; + font-size: 0.8em; + text-align: center; + background-color: #222; +} + +p { + margin: 0.8em 0 0.5em 0; +} + +.section p img.math { + margin: 0; +} + + +.section p img { + margin: 1em 2em; +} + + +/* MOBILE LAYOUT -------------------------------------------------------------- */ + +@media screen and (max-width: 600px) { + + h1, h2, h3, h4, h5 { + position: relative; + } + + ul { + padding-left: 1.25em; + } + + div.bodywrapper a.headerlink, #indices-and-tables h1 a { + color: #e6e6e6; + font-size: 80%; + float: right; + line-height: 1.8; + position: absolute; + right: -0.7em; + visibility: inherit; + } + + div.bodywrapper h1 a.headerlink, #indices-and-tables h1 a { + line-height: 1.5; + } + + pre { + font-size: 0.7em; + overflow: auto; + word-wrap: break-word; + white-space: pre-wrap; + } + + div.related ul { + height: 2.5em; + padding: 0; + text-align: left; + } + + div.related ul li { + clear: both; + color: #465158; + padding: 0.2em 0; + } + + div.related ul li:last-child { + border-bottom: 1px dotted #8ca1af; + padding-bottom: 0.4em; + margin-bottom: 1em; + width: 100%; + } + + div.related ul li a { + color: #fff; + padding-right: 0; + } + + div.related ul li a:hover { + background: inherit; + color: inherit; + } + + div.related ul li.right { + clear: none; + padding: 0.65em 0; + margin-bottom: 0.5em; + } + + div.related ul li.right a { + color: #fff; + padding-right: 0.8em; + } + + div.related ul li.right a:hover { + background-color: #8ca1af; + } + + div.body { + clear: both; + min-width: 0; + word-wrap: break-word; + } + + div.bodywrapper { + margin: 0 0 0 0; + } + + div.sphinxsidebar { + float: none; + margin: 0; + width: auto; + } + + div.sphinxsidebar input[type="text"] { + height: 2em; + line-height: 2em; + width: 70%; + } + + div.sphinxsidebar input[type="submit"] { + height: 2em; + margin-left: 0.5em; + width: 20%; + } + + div.sphinxsidebar p.searchtip { + background: inherit; + margin-bottom: 1em; + } + + div.sphinxsidebar ul li, div.sphinxsidebar p.topless { + white-space: normal; + } + + .bodywrapper img { + display: block; + margin-left: auto; + margin-right: auto; + max-width: 100%; + } + + div.documentwrapper { + float: none; + } + + div.admonition, div.warning, pre, blockquote { + margin-left: 0em; + margin-right: 0em; + } + + .body p img { + margin: 0; + } + + #searchbox { + background: transparent; + } + + .related:not(:first-child) li { + display: none; + } + + .related:not(:first-child) li.right { + display: block; + } + + div.footer { + padding: 1em; + } + + .rtd_doc_footer .rtd-badge { + float: none; + margin: 1em auto; + position: static; + } + + .rtd_doc_footer .rtd-badge.revsys-inline { + margin-right: auto; + margin-bottom: 2em; + } + + table.indextable { + display: block; + width: auto; + } + + .indextable tr { + display: block; + } + + .indextable td { + display: block; + padding: 0; + width: auto !important; + } + + .indextable td dt { + margin: 1em 0; + } + + ul.search { + margin-left: 0.25em; + } + + ul.search li div.context { + font-size: 90%; + line-height: 1.1; + margin-bottom: 1; + margin-left: 0; + } + +} + +.donate { + text-align: center; +} + +.donate .flattr { + margin-top: 1.5em; +} diff --git a/vendor/casperjs/docs/_themes/casperjs/static/casperjs-light.css b/vendor/casperjs/docs/_themes/casperjs/static/casperjs-light.css new file mode 100755 index 0000000..96510b8 --- /dev/null +++ b/vendor/casperjs/docs/_themes/casperjs/static/casperjs-light.css @@ -0,0 +1,887 @@ +/* + * rtd.css + * ~~~~~~~~~~~~~~~ + * + * Sphinx stylesheet -- sphinxdoc theme. Originally created by + * Armin Ronacher for Werkzeug. + * + * Customized for ReadTheDocs by Eric Pierce & Eric Holscher + * + * :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/* RTD colors + * light blue: #e8ecef + * medium blue: #8ca1af + * dark blue: #465158 + * dark grey: #444444 + * + * white hover: #d1d9df; + * medium blue hover: #697983; + * green highlight: #8ecc4c + * light blue (project bar): #e8ecef + */ + +@import url("basic.css"); + +/* PAGE LAYOUT -------------------------------------------------------------- */ + +body { + font: 100%/1.5 "ff-meta-web-pro-1","ff-meta-web-pro-2",Arial,"Helvetica Neue",sans-serif; + text-align: center; + color: black; + background-color: #465158; + padding: 0; + margin: 0; +} + +img { + border: 0; + max-width: 100%; +} + +div.document { + text-align: left; + background-color: #e8ecef; +} + +div.bodywrapper { + background-color: #ffffff; + border-left: 1px solid #ccc; + border-bottom: 1px solid #ccc; + margin: 0 0 0 16em; +} + +div.body { + margin: 0; + padding: 0.5em 1.3em; + min-width: 20em; +} + +div.related { + font-size: 1em; + background-color: #465158; +} + +div.documentwrapper { + float: left; + width: 100%; + background-color: #e8ecef; +} + + +/* HEADINGS --------------------------------------------------------------- */ + +h1 { + margin: 0; + padding: 0.7em 0 0.3em 0; + font-size: 1.5em; + line-height: 1.15; + color: #111; + clear: both; +} + +h2 { + margin: 2em 0 0.2em 0; + font-size: 1.35em; + padding: 0; + color: #465158; +} + +h3 { + margin: 1em 0 -0.3em 0; + font-size: 1.2em; + color: #6c818f; +} + +div.body h1 a, div.body h2 a, div.body h3 a, div.body h4 a, div.body h5 a, div.body h6 a { + color: black; +} + +h1 a.anchor, h2 a.anchor, h3 a.anchor, h4 a.anchor, h5 a.anchor, h6 a.anchor { + display: none; + margin: 0 0 0 0.3em; + padding: 0 0.2em 0 0.2em; + color: #aaa !important; +} + +h1:hover a.anchor, h2:hover a.anchor, h3:hover a.anchor, h4:hover a.anchor, +h5:hover a.anchor, h6:hover a.anchor { + display: inline; +} + +h1 a.anchor:hover, h2 a.anchor:hover, h3 a.anchor:hover, h4 a.anchor:hover, +h5 a.anchor:hover, h6 a.anchor:hover { + color: #777; + background-color: #eee; +} + + +/* LINKS ------------------------------------------------------------------ */ + +/* Normal links get a pseudo-underline */ +a { + color: #444; + text-decoration: none; + border-bottom: 1px solid #ccc; +} + +/* Links in sidebar, TOC, index trees and tables have no underline */ +.sphinxsidebar a, +.toctree-wrapper a, +.indextable a, +#indices-and-tables a { + color: #444; + text-decoration: none; + border-bottom: none; +} + +/* Most links get an underline-effect when hovered */ +a:hover, +div.toctree-wrapper a:hover, +.indextable a:hover, +#indices-and-tables a:hover { + color: #111; + text-decoration: none; + border-bottom: 1px solid #111; +} + +/* Footer links */ +div.footer a { + color: #86989B; + text-decoration: none; + border: none; +} +div.footer a:hover { + color: #a6b8bb; + text-decoration: underline; + border: none; +} + +/* Permalink anchor (subtle grey with a red hover) */ +div.body a.headerlink { + color: #ccc; + font-size: 1em; + margin-left: 6px; + padding: 0 4px 0 4px; + text-decoration: none; + border: none; +} +div.body a.headerlink:hover { + color: #c60f0f; + border: none; +} + + +/* NAVIGATION BAR --------------------------------------------------------- */ + +div.related ul { + height: 2.5em; +} + +div.related ul li { + margin: 0; + padding: 0.65em 0; + float: left; + display: block; + color: white; /* For the >> separators */ + font-size: 0.8em; +} + +div.related ul li.right { + float: right; + margin-right: 5px; + color: transparent; /* Hide the | separators */ +} + +/* "Breadcrumb" links in nav bar */ +div.related ul li a { + order: none; + background-color: inherit; + font-weight: bold; + margin: 6px 0 6px 4px; + line-height: 1.75em; + color: #ffffff; + padding: 0.4em 0.8em; + border: none; + border-radius: 3px; +} +/* previous / next / modules / index links look more like buttons */ +div.related ul li.right a { + margin: 0.375em 0; + background-color: #697983; + text-shadow: 0 1px rgba(0, 0, 0, 0.5); + border-radius: 3px; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; +} +/* All navbar links light up as buttons when hovered */ +div.related ul li a:hover { + background-color: #8ca1af; + color: #ffffff; + text-decoration: none; + border-radius: 3px; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; +} +/* Take extra precautions for tt within links */ +a tt, +div.related ul li a tt { + background: inherit !important; + color: inherit !important; +} + + +/* SIDEBAR ---------------------------------------------------------------- */ + +div.sphinxsidebarwrapper { + padding: 0; +} + +div.sphinxsidebar { + margin: 0; + margin-left: -100%; + float: left; + top: 3em; + left: 0; + padding: 0 1em; + width: 14em; + font-size: 1em; + text-align: left; + background-color: #e8ecef; +} + +div.sphinxsidebar img { + max-width: 12em; +} + +div.sphinxsidebar input[type="image"] { + display: inline; + float: none; + border: 0; +} + +div.sphinxsidebar h3, +div.sphinxsidebar h4, +div.sphinxsidebar p.logo { + margin: 1.2em 0 0.3em 0; + font-size: 1em; + padding: 0; + color: #222222; + font-family: "ff-meta-web-pro-1", "ff-meta-web-pro-2", "Arial", "Helvetica Neue", sans-serif; +} + +div.sphinxsidebar h3 a { + color: #444444; +} + +div.sphinxsidebar ul, +div.sphinxsidebar p { + margin-top: 0; + padding-left: 0; + line-height: 130%; + background-color: #e8ecef; +} + +/* No bullets for nested lists, but a little extra indentation */ +div.sphinxsidebar ul ul { + list-style-type: none; + margin-left: 1.5em; + padding: 0; +} + +/* A little top/bottom padding to prevent adjacent links' borders + * from overlapping each other */ +div.sphinxsidebar ul li { + padding: 1px 0; +} + +/* A little left-padding to make these align with the ULs */ +div.sphinxsidebar p.topless { + padding-left: 0 0 0 1em; +} + +/* Make these into hidden one-liners */ +div.sphinxsidebar ul li, +div.sphinxsidebar p.topless { + white-space: nowrap; + overflow: hidden; +} +/* ...which become visible when hovered */ +div.sphinxsidebar ul li:hover, +div.sphinxsidebar p.topless:hover { + overflow: visible; +} + +/* Search text box and "Go" button */ +#searchbox { + margin-top: 2em; + margin-bottom: 1em; + background: #ddd; + padding: 0.5em; + border-radius: 6px; + -moz-border-radius: 6px; + -webkit-border-radius: 6px; +} +#searchbox h3 { + margin-top: 0; +} + +/* Make search box and button abut and have a border */ +input, +div.sphinxsidebar input { + border: 1px solid #999; + float: left; +} + +/* Search textbox */ +input[type="text"] { + margin: 0; + padding: 0 3px; + height: 20px; + width: 144px; + border-top-left-radius: 3px; + border-bottom-left-radius: 3px; + -moz-border-radius-topleft: 3px; + -moz-border-radius-bottomleft: 3px; + -webkit-border-top-left-radius: 3px; + -webkit-border-bottom-left-radius: 3px; +} +/* Search button */ +input[type="submit"] { + margin: 0 0 0 -1px; /* -1px prevents a double-border with textbox */ + height: 22px; + color: #444; + background-color: #e8ecef; + padding: 1px 4px; + font-weight: bold; + border-top-right-radius: 3px; + border-bottom-right-radius: 3px; + -moz-border-radius-topright: 3px; + -moz-border-radius-bottomright: 3px; + -webkit-border-top-right-radius: 3px; + -webkit-border-bottom-right-radius: 3px; +} +input[type="submit"]:hover { + color: #ffffff; + background-color: #8ecc4c; +} + +div.sphinxsidebar p.searchtip { + clear: both; + padding: 0.5em 0 0 0; + background: #ddd; + color: #666; + font-size: 0.9em; +} + +/* Sidebar links are unusual */ +div.sphinxsidebar li a, +div.sphinxsidebar p a { + background: #e8ecef; /* In case links overlap main content */ + border-radius: 3px; + -moz-border-radius: 3px; + -webkit-border-radius: 3px; + border: 1px solid transparent; /* To prevent things jumping around on hover */ + padding: 0 5px 0 5px; +} +div.sphinxsidebar li a:hover, +div.sphinxsidebar p a:hover { + color: #111; + text-decoration: none; + border: 1px solid #888; +} +div.sphinxsidebar p.logo a { + border: 0; +} + +/* Tweak any link appearing in a heading */ +div.sphinxsidebar h3 a { +} + + + + +/* OTHER STUFF ------------------------------------------------------------ */ + +cite, code, tt { + font-family: 'Consolas', 'Deja Vu Sans Mono', + 'Bitstream Vera Sans Mono', monospace; + font-size: 0.95em; + letter-spacing: 0.01em; +} + +tt { + background-color: #f2f2f2; + color: #444; +} + +tt.descname, tt.descclassname, tt.xref { + border: 0; +} + +hr { + border: 1px solid #abc; + margin: 2em; +} + + +pre, #_fontwidthtest { + font-family: 'Consolas', 'Deja Vu Sans Mono', + 'Bitstream Vera Sans Mono', monospace; + margin: 1em 2em; + font-size: 0.95em; + letter-spacing: 0.015em; + line-height: 120%; + padding: 0.5em; + border: 1px solid #ccc; + background-color: #eee; + border-radius: 6px; + -moz-border-radius: 6px; + -webkit-border-radius: 6px; +} + +pre a { + color: inherit; + text-decoration: underline; +} + +td.linenos pre { + margin: 1em 0em; +} + +td.code pre { + margin: 1em 0em; +} + +div.quotebar { + background-color: #f8f8f8; + max-width: 250px; + float: right; + padding: 2px 7px; + border: 1px solid #ccc; +} + +div.topic { + background-color: #f8f8f8; +} + +table { + border-collapse: collapse; + margin: 0 -0.5em 0 -0.5em; +} + +table td, table th { + padding: 0.2em 0.5em 0.2em 0.5em; +} + + +/* ADMONITIONS AND WARNINGS ------------------------------------------------- */ + +/* Shared by admonitions, warnings and sidebars */ +div.admonition, +div.warning, +div.sidebar { + font-size: 0.9em; + margin: 2em; + padding: 0; + /* + border-radius: 6px; + -moz-border-radius: 6px; + -webkit-border-radius: 6px; + */ +} +div.admonition p, +div.warning p, +div.sidebar p { + margin: 0.5em 1em 0.5em 1em; + padding: 0; +} +div.admonition pre, +div.warning pre, +div.sidebar pre { + margin: 0.4em 1em 0.4em 1em; +} +div.admonition p.admonition-title, +div.warning p.admonition-title, +div.sidebar p.sidebar-title { + margin: 0; + padding: 0.1em 0 0.1em 0.5em; + color: white; + font-weight: bold; + font-size: 1.1em; + text-shadow: 0 1px rgba(0, 0, 0, 0.5); +} +div.admonition ul, div.admonition ol, +div.warning ul, div.warning ol, +div.sidebar ul, div.sidebar ol { + margin: 0.1em 0.5em 0.5em 3em; + padding: 0; +} + + +/* Admonitions and sidebars only */ +div.admonition, div.sidebar { + border: 1px solid #609060; + background-color: #e9ffe9; +} +div.admonition p.admonition-title, +div.sidebar p.sidebar-title { + background-color: #70A070; + border-bottom: 1px solid #609060; +} + + +/* Warnings only */ +div.warning { + border: 1px solid #900000; + background-color: #ffe9e9; +} +div.warning p.admonition-title { + background-color: #b04040; + border-bottom: 1px solid #900000; +} + + +/* Sidebars only */ +div.sidebar { + max-width: 30%; +} + + + +div.versioninfo { + margin: 1em 0 0 0; + border: 1px solid #ccc; + background-color: #DDEAF0; + padding: 8px; + line-height: 1.3em; + font-size: 0.9em; +} + +.viewcode-back { + font-family: 'Lucida Grande', 'Lucida Sans Unicode', 'Geneva', + 'Verdana', sans-serif; +} + +div.viewcode-block:target { + background-color: #f4debf; + border-top: 1px solid #ac9; + border-bottom: 1px solid #ac9; +} + +dl { + margin: 1em 0 2.5em 0; +} + +/* Highlight target when you click an internal link */ +dt:target { + background: #ffe080; +} +/* Don't highlight whole divs */ +div.highlight { + background: transparent; +} +/* But do highlight spans (so search results can be highlighted) */ +span.highlight { + background: #ffe080; +} + +div.footer { + background-color: #465158; + color: #eeeeee; + padding: 0 2em 2em 2em; + clear: both; + font-size: 0.8em; + text-align: center; +} + +p { + margin: 0.8em 0 0.5em 0; +} + +.section p img.math { + margin: 0; +} + + +.section p img { + margin: 1em 2em; +} + + +/* MOBILE LAYOUT -------------------------------------------------------------- */ + +@media screen and (max-width: 600px) { + + h1, h2, h3, h4, h5 { + position: relative; + } + + ul { + padding-left: 1.25em; + } + + div.bodywrapper a.headerlink, #indices-and-tables h1 a { + color: #e6e6e6; + font-size: 80%; + float: right; + line-height: 1.8; + position: absolute; + right: -0.7em; + visibility: inherit; + } + + div.bodywrapper h1 a.headerlink, #indices-and-tables h1 a { + line-height: 1.5; + } + + pre { + font-size: 0.7em; + overflow: auto; + word-wrap: break-word; + white-space: pre-wrap; + } + + div.related ul { + height: 2.5em; + padding: 0; + text-align: left; + } + + div.related ul li { + clear: both; + color: #465158; + padding: 0.2em 0; + } + + div.related ul li:last-child { + border-bottom: 1px dotted #8ca1af; + padding-bottom: 0.4em; + margin-bottom: 1em; + width: 100%; + } + + div.related ul li a { + color: #465158; + padding-right: 0; + } + + div.related ul li a:hover { + background: inherit; + color: inherit; + } + + div.related ul li.right { + clear: none; + padding: 0.65em 0; + margin-bottom: 0.5em; + } + + div.related ul li.right a { + color: #fff; + padding-right: 0.8em; + } + + div.related ul li.right a:hover { + background-color: #8ca1af; + } + + div.body { + clear: both; + min-width: 0; + word-wrap: break-word; + } + + div.bodywrapper { + margin: 0 0 0 0; + } + + div.sphinxsidebar { + float: none; + margin: 0; + width: auto; + } + + div.sphinxsidebar input[type="text"] { + height: 2em; + line-height: 2em; + width: 70%; + } + + div.sphinxsidebar input[type="submit"] { + height: 2em; + margin-left: 0.5em; + width: 20%; + } + + div.sphinxsidebar p.searchtip { + background: inherit; + margin-bottom: 1em; + } + + div.sphinxsidebar ul li, div.sphinxsidebar p.topless { + white-space: normal; + } + + .bodywrapper img { + display: block; + margin-left: auto; + margin-right: auto; + max-width: 100%; + } + + div.documentwrapper { + float: none; + } + + div.admonition, div.warning, pre, blockquote { + margin-left: 0em; + margin-right: 0em; + } + + .body p img { + margin: 0; + } + + #searchbox { + background: transparent; + } + + .related:not(:first-child) li { + display: none; + } + + .related:not(:first-child) li.right { + display: block; + } + + div.footer { + padding: 1em; + } + + .rtd_doc_footer .rtd-badge { + float: none; + margin: 1em auto; + position: static; + } + + .rtd_doc_footer .rtd-badge.revsys-inline { + margin-right: auto; + margin-bottom: 2em; + } + + table.indextable { + display: block; + width: auto; + } + + .indextable tr { + display: block; + } + + .indextable td { + display: block; + padding: 0; + width: auto !important; + } + + .indextable td dt { + margin: 1em 0; + } + + ul.search { + margin-left: 0.25em; + } + + ul.search li div.context { + font-size: 90%; + line-height: 1.1; + margin-bottom: 1; + margin-left: 0; + } +} + +.donate { + text-align: center; +} + +.donate .flattr { + margin-top: 1.5em; +} + + +.highlight .hll { background-color: #ffffcc } +.highlight { background: #eeffcc; } +.highlight .c { color: #408090; font-style: italic } /* Comment */ +.highlight .err { border: 1px solid #FF0000 } /* Error */ +.highlight .k { color: #007020; font-weight: bold } /* Keyword */ +.highlight .o { color: #666666 } /* Operator */ +.highlight .cm { color: #408090; font-style: italic } /* Comment.Multiline */ +.highlight .cp { color: #007020 } /* Comment.Preproc */ +.highlight .c1 { color: #408090; font-style: italic } /* Comment.Single */ +.highlight .cs { color: #408090; background-color: #fff0f0 } /* Comment.Special */ +.highlight .gd { color: #A00000 } /* Generic.Deleted */ +.highlight .ge { font-style: italic } /* Generic.Emph */ +.highlight .gr { color: #FF0000 } /* Generic.Error */ +.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ +.highlight .gi { color: #00A000 } /* Generic.Inserted */ +.highlight .go { color: #303030 } /* Generic.Output */ +.highlight .gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */ +.highlight .gs { font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +.highlight .gt { color: #0040D0 } /* Generic.Traceback */ +.highlight .kc { color: #007020; font-weight: bold } /* Keyword.Constant */ +.highlight .kd { color: #007020; font-weight: bold } /* Keyword.Declaration */ +.highlight .kn { color: #007020; font-weight: bold } /* Keyword.Namespace */ +.highlight .kp { color: #007020 } /* Keyword.Pseudo */ +.highlight .kr { color: #007020; font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #902000 } /* Keyword.Type */ +.highlight .m { color: #208050 } /* Literal.Number */ +.highlight .s { color: #4070a0 } /* Literal.String */ +.highlight .na { color: #4070a0 } /* Name.Attribute */ +.highlight .nb { color: #007020 } /* Name.Builtin */ +.highlight .nc { color: #0e84b5; font-weight: bold } /* Name.Class */ +.highlight .no { color: #60add5 } /* Name.Constant */ +.highlight .nd { color: #555555; font-weight: bold } /* Name.Decorator */ +.highlight .ni { color: #d55537; font-weight: bold } /* Name.Entity */ +.highlight .ne { color: #007020 } /* Name.Exception */ +.highlight .nf { color: #06287e } /* Name.Function */ +.highlight .nl { color: #002070; font-weight: bold } /* Name.Label */ +.highlight .nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */ +.highlight .nt { color: #062873; font-weight: bold } /* Name.Tag */ +.highlight .nv { color: #bb60d5 } /* Name.Variable */ +.highlight .nx { color: #111111 } /* Std */ +.highlight .ow { color: #007020; font-weight: bold } /* Operator.Word */ +.highlight .w { color: #bbbbbb } /* Text.Whitespace */ +.highlight .mf { color: #208050 } /* Literal.Number.Float */ +.highlight .mh { color: #208050 } /* Literal.Number.Hex */ +.highlight .mi { color: #208050 } /* Literal.Number.Integer */ +.highlight .mo { color: #208050 } /* Literal.Number.Oct */ +.highlight .sb { color: #4070a0 } /* Literal.String.Backtick */ +.highlight .sc { color: #4070a0 } /* Literal.String.Char */ +.highlight .sd { color: #4070a0; font-style: italic } /* Literal.String.Doc */ +.highlight .s2 { color: #4070a0 } /* Literal.String.Double */ +.highlight .se { color: #4070a0; font-weight: bold } /* Literal.String.Escape */ +.highlight .sh { color: #4070a0 } /* Literal.String.Heredoc */ +.highlight .si { color: #70a0d0; font-style: italic } /* Literal.String.Interpol */ +.highlight .sx { color: #c65d09 } /* Literal.String.Other */ +.highlight .sr { color: #235388 } /* Literal.String.Regex */ +.highlight .s1 { color: #4070a0 } /* Literal.String.Single */ +.highlight .ss { color: #517918 } /* Literal.String.Symbol */ +.highlight .bp { color: #007020 } /* Name.Builtin.Pseudo */ +.highlight .vc { color: #bb60d5 } /* Name.Variable.Class */ +.highlight .vg { color: #bb60d5 } /* Name.Variable.Global */ +.highlight .vi { color: #bb60d5 } /* Name.Variable.Instance */ +.highlight .il { color: #208050 } /* Literal.Number.Integer.Long */ + +/* https://github.com/n1k0/casperjs-docs/issues/2 */ +#casperjs-documentation img { + -webkit-filter: drop-shadow(0 1px 20px rgba(0,0,0,.5)); + -moz-filter: drop-shadow(0 1px 20px rgba(0,0,0,.5)); + -ms-filter: drop-shadow(0 1px 20px rgba(0,0,0,.5)); + -o-filter: drop-shadow(0 1px 20px rgba(0,0,0,.5)); + filter: drop-shadow(0 1px 20px rgba(0,0,0,.5)); +} diff --git a/vendor/casperjs/docs/_themes/casperjs/static/style-switcher.js b/vendor/casperjs/docs/_themes/casperjs/static/style-switcher.js new file mode 100755 index 0000000..1691df5 --- /dev/null +++ b/vendor/casperjs/docs/_themes/casperjs/static/style-switcher.js @@ -0,0 +1,106 @@ +/** + * http://www.alistapart.com/articles/alternate/ + * + * var cookie = readCookie("style"); + * var title = cookie ? cookie : getPreferredStyleSheet(); + * setActiveStyleSheet(title); + */ +(function(exports, $) { + function setActiveStyleSheet(title) { + var i, a, main; + for (i = 0; (a = document.getElementsByTagName("link")[i]); i++) { + if (a.getAttribute("rel").indexOf("style") !== -1 && a.getAttribute("title")) { + a.disabled = true; + if (a.getAttribute("title") === title) { + a.disabled = false; + } + } + } + } + exports.setActiveStyleSheet = setActiveStyleSheet; + + function getActiveStyleSheet() { + var i, a; + for (i = 0; (a = document.getElementsByTagName("link")[i]); i++) { + if (a.getAttribute("rel").indexOf("style") !== -1 && a.getAttribute("title") && !a.disabled) { + return a.getAttribute("title"); + } + } + return null; + } + exports.getActiveStyleSheet = getActiveStyleSheet; + + function getPreferredStyleSheet() { + var i, a; + for (i = 0; (a = document.getElementsByTagName("link")[i]); i++) { + if (a.getAttribute("rel").indexOf("style") !== -1 && + a.getAttribute("rel").indexOf("alt") === -1 && + a.getAttribute("title")) { + return a.getAttribute("title"); + } + } + return null; + } + exports.getPreferredStyleSheet = getPreferredStyleSheet; + + function createCookie(name, value, days) { + var expires = ""; + if (days) { + var date = new Date(); + date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000)); + expires = "; expires=" + date.toGMTString(); + } + document.cookie = name + "=" + value + expires + "; path=/"; + } + + function readCookie(name) { + var nameEQ = name + "="; + var ca = document.cookie.split(';'); + for (var i = 0; i < ca.length; i++) { + var c = ca[i]; + while (c.charAt(0) === ' ') { + c = c.substring(1, c.length); + } + if (c.indexOf(nameEQ) === 0) { + return c.substring(nameEQ.length, c.length); + } + } + return null; + } + + function createSwitcher() { + var $nav = $('.related').find('ul'); + var styles = $('link').filter(function(i, link){ + return $(link).attr('rel').indexOf('style') > -1 && $(link).attr('title'); + }).map(function(i, link) { + return $(link).attr('title'); + }); + $(styles).each(function(i, style) { + var $link = $('').attr('href', '#') + .attr('title', style) + .addClass('style-switch') + .text(style); + $nav.prepend($('
  • ').addClass('right').append($link)); + }); + $('.style-switch').bind('click', function(event) { + event.preventDefault(); + setActiveStyleSheet($(this).attr('title')); + }); + } + + exports.onload = function(e) { + var cookie = readCookie("style"); + var title = cookie ? cookie : getPreferredStyleSheet(); + setActiveStyleSheet(title); + createSwitcher(); + } + + exports.onunload = function(e) { + var title = getActiveStyleSheet(); + createCookie("style", title, 365); + } + + var cookie = readCookie("style"); + var title = cookie ? cookie : getPreferredStyleSheet(); + setActiveStyleSheet(title); +})(window, window.jQuery); diff --git a/vendor/casperjs/docs/_themes/casperjs/theme.conf b/vendor/casperjs/docs/_themes/casperjs/theme.conf new file mode 100755 index 0000000..89e03bb --- /dev/null +++ b/vendor/casperjs/docs/_themes/casperjs/theme.conf @@ -0,0 +1,2 @@ +[theme] +inherit = basic diff --git a/vendor/casperjs/docs/changelog.rst b/vendor/casperjs/docs/changelog.rst new file mode 100755 index 0000000..8cc6b47 --- /dev/null +++ b/vendor/casperjs/docs/changelog.rst @@ -0,0 +1,4 @@ +Changelog +========= + +The CasperJS changelog is `hosted on github `_. diff --git a/vendor/casperjs/docs/cli.rst b/vendor/casperjs/docs/cli.rst new file mode 100755 index 0000000..fa7fc3b --- /dev/null +++ b/vendor/casperjs/docs/cli.rst @@ -0,0 +1,164 @@ +.. _cli: + +.. index:: Command line, CLI, PhantomJS, Shell, arguments, options + +====================== +Using the command line +====================== + +CasperJS ships with a built-in command line parser on top of PhantomJS' one, located in the ``cli`` module; it exposes passed arguments as **positional ones** and **named options** + +But no worries for manipulating the ``cli`` module parsing API, a ``Casper`` instance always contains a ready to use ``cli`` property, allowing easy access of all these parameters. + +Let's consider this simple casper script:: + + var casper = require("casper").create(); + + casper.echo("Casper CLI passed args:"); + require("utils").dump(casper.cli.args); + + casper.echo("Casper CLI passed options:"); + require("utils").dump(casper.cli.options); + + casper.exit(); + +.. note:: + + Please note the two ``casper-path`` and ``cli`` options; these are passed to the casper script through the ``casperjs`` Python executable. + +Execution results:: + + $ casperjs test.js arg1 arg2 arg3 --foo=bar --plop anotherarg + Casper CLI passed args: [ + "arg1", + "arg2", + "arg3", + "anotherarg" + ] + Casper CLI passed options: { + "casper-path": "/Users/niko/Sites/casperjs", + "cli": true, + "foo": "bar", + "plop": true + } + +Getting, checking or dropping parameters:: + + var casper = require("casper").create(); + casper.echo(casper.cli.has(0)); + casper.echo(casper.cli.get(0)); + casper.echo(casper.cli.has(3)); + casper.echo(casper.cli.get(3)); + casper.echo(casper.cli.has("foo")); + casper.echo(casper.cli.get("foo")); + casper.cli.drop("foo"); + casper.echo(casper.cli.has("foo")); + casper.echo(casper.cli.get("foo")); + casper.exit(); + +Execution results: + +.. code-block:: text + + $ casperjs test.js arg1 arg2 arg3 --foo=bar --plop anotherarg + true + arg1 + true + anotherarg + true + bar + false + undefined + +.. hint:: + + What if you want to check if any arg or option has been passed to your script? Here you go:: + + // removing default options passed by the Python executable + casper.cli.drop("cli"); + casper.cli.drop("casper-path"); + + if (casper.cli.args.length === 0 && Object.keys(casper.cli.options).length === 0) { + casper.echo("No arg nor option passed").exit(); + } + +`casperjs` native options +------------------------- + +.. versionadded:: 1.1 + +.. index:: Logging, log levels, SlimerJS + +The `casperjs` command has three available options: + +- ``--direct``: to prints out log messages to the console +- ``--log-level=[debug|info|warning|error]`` to set the :ref:`logging level ` +- ``--engine=[phantomjs|slimerjs]`` to select the browser engine you want to use. CasperJS + supports PhantomJS (default) that runs Webkit, and SlimerJS that runs Gecko. + +.. warning:: + + .. deprecated:: 1.1 + + ``--direct`` option has been renamed to ``--verbose``, though ``--direct`` will still works, while is to be considered deprecated. + +Example: + +.. code-block:: text + + $ casperjs --verbose --log-level=debug myscript.js + +Last but not least, you can still use all PhantomJS standard CLI options as you would do with any other phantomjs script: + +.. code-block:: text + + $ casperjs --web-security=no --cookies-file=/tmp/mycookies.txt myscript.js + +.. hint:: + + To remember what the native phantomjs available cli options are, run the ``phantomjs --help`` command. + SlimerJS supports almost same options as PhantomJS. + +.. index:: Raw values + +Raw parameter values +-------------------- + +.. versionadded:: 1.0 + +By default, the cli object will process every passed argument & cast them to the appropriate detected type; example script:: + + var casper = require('casper').create(); + var utils = require('utils'); + + utils.dump(casper.cli.get('foo')); + + casper.exit(); + +If you run this script: + +.. code-block:: text + + $ casperjs c.js --foo=01234567 + 1234567 + +As you can see, the ``01234567`` value has been cast to a *Number*. + +Sometimes, you just want the original string; then you can use the ``raw`` property of the ``cli`` object, which contains the raw values passed parameters:: + + var casper = require('casper').create(); + var utils = require('utils'); + + utils.dump(casper.cli.get('foo')); + utils.dump(casper.cli.raw.get('foo')); + + casper.exit(); + +Sample usage: + +.. code-block:: text + + $ casperjs c.js --foo=01234567 + 1234567 + "01234567" + diff --git a/vendor/casperjs/docs/conf.py b/vendor/casperjs/docs/conf.py new file mode 100755 index 0000000..d1513dc --- /dev/null +++ b/vendor/casperjs/docs/conf.py @@ -0,0 +1,259 @@ +# -*- coding: utf-8 -*- +# +# CasperJS documentation +# +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +#sys.path.insert(0, os.path.abspath('.')) + +from datetime import date + +# -- General configuration ----------------------------------------------------- + +# If your documentation needs a minimal Sphinx version, state it here. +#needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be extensions +# coming with Sphinx (named 'sphinx.ext.*') or your custom ones. +extensions = ['sphinx.ext.autodoc', 'sphinx.ext.extlinks'] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +highlight_language = 'javascript' + +# The suffix of source filenames. +source_suffix = '.rst' + +# Prolog +rst_prolog = None + +# The encoding of source files. +source_encoding = 'utf-8' + +# The master toctree document. +master_doc = 'index' + +# General information about the project. +project = u'CasperJS' +copyright = (u'2011-%d Nicolas Perriault and contributors. CasperJS logo by Jeremy Forveille' + % date.today().year) + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The short X.Y version. +version = '1.1' +# The full version, including alpha/beta/rc tags. +release = '1.1.0-DEV' + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +#language = None + +# There are two options for replacing |today|: either, you set today to some +# non-false value, then it is used: +#today = '' +# Else, today_fmt is used as the format for a strftime call. +#today_fmt = '%B %d, %Y' + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +exclude_patterns = ['_build', 'README.md'] + +# The reST default role (used for this markup: `text`) to use for all documents. +#default_role = None + +# If true, '()' will be appended to :func: etc. cross-reference text. +#add_function_parentheses = True + +# If true, the current module name will be prepended to all description +# unit titles (such as .. function::). +#add_module_names = True + +# If true, sectionauthor and moduleauthor directives will be shown in the +# output. They are ignored by default. +#show_authors = False + +# The name of the Pygments (syntax highlighting) style to use. +#pygments_style = 'default' + +# A list of ignored prefixes for module index sorting. +#modindex_common_prefix = [] + + +# -- Options for HTML output --------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +html_theme = 'casperjs' + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +#html_theme_options = {} + +# Add any paths that contain custom themes here, relative to this directory. +html_theme_path = ['_themes'] + +# The name for this set of Sphinx documents. If None, it defaults to +# " v documentation". +#html_title = None + +# A shorter title for the navigation bar. Default is the same as html_title. +#html_short_title = None + +# The name of an image file (relative to this directory) to place at the top +# of the sidebar. +#html_logo = None + +# The name of an image file (within the static path) to use as favicon of the +# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 +# pixels large. +html_favicon = 'casperjs-favicon.ico' + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] + +# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, +# using the given strftime format. +#html_last_updated_fmt = '%b %d, %Y' + +# If true, SmartyPants will be used to convert quotes and dashes to +# typographically correct entities. +#html_use_smartypants = True + +# Custom sidebar templates, maps document names to template names. +html_sidebars = { + '*': [ + 'globaltoc.html', + 'relations.html', + 'sourcelink.html', + 'searchbox.html', + 'addon.html' + ], + 'modules/*': [ + 'localtoc.html', + 'globaltoc.html', + 'relations.html', + 'sourcelink.html', + 'searchbox.html', + 'addon.html' + ], +} + +# Additional templates that should be rendered to pages, maps page names to +# template names. +#html_additional_pages = {} + +# If false, no module index is generated. +#html_domain_indices = True + +# If false, no index is generated. +#html_use_index = True + +# If true, the index is split into individual pages for each letter. +#html_split_index = False + +# If true, links to the reST sources are added to the pages. +#html_show_sourcelink = True + +# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. +#html_show_sphinx = True + +# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. +#html_show_copyright = True + +# If true, an OpenSearch description file will be output, and all pages will +# contain a tag referring to it. The value of this option must be the +# base URL from which the finished HTML is served. +#html_use_opensearch = '' + +# This is the file name suffix for HTML files (e.g. ".xhtml"). +#html_file_suffix = None + +# Output file base name for HTML help builder. +htmlhelp_basename = 'casper-docs' + + +# -- Options for LaTeX output -------------------------------------------------- + +latex_elements = { +# The paper size ('letterpaper' or 'a4paper'). +'papersize': 'letterpaper', + +# The font size ('10pt', '11pt' or '12pt'). +'pointsize': '10pt', + +# Additional stuff for the LaTeX preamble. +#'preamble': '', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, author, documentclass [howto/manual]). +latex_documents = [ + ('index', 'casperjs.tex', 'CasperJs Documentation', + 'Nicolas Perriault', 'manual'), +] + +# The name of an image file (relative to this directory) to place at the top of +# the title page. +#latex_logo = None + +# For "manual" documents, if this is true, then toplevel headings are parts, +# not chapters. +#latex_use_parts = False + +# If true, show page references after internal links. +#latex_show_pagerefs = False + +# If true, show URL addresses after external links. +#latex_show_urls = False + +# Documents to append as an appendix to all manuals. +#latex_appendices = [] + +# If false, no module index is generated. +#latex_domain_indices = True + + +# -- Options for manual page output -------------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + ('index', 'casperjs', u'casperjs documentation', [u'Nicolas Perriault'], 1) +] + +# If true, show URL addresses after external links. +#man_show_urls = False + + +# -- Options for Texinfo output ------------------------------------------------ + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + ('index', 'CasperJS', u'CasperJS Documentation', + u'Nicolas Perriault', 'CasperJS', 'CasperJS docs.', 'Miscellaneous'), +] + +# Documents to append as an appendix to all manuals. +#texinfo_appendices = [] + +# If false, no module index is generated. +#texinfo_domain_indices = True + +# How to display URL addresses: 'footnote', 'no', or 'inline'. +#texinfo_show_urls = 'footnote' + + +extlinks = { + 'issue': ('https://github.com/n1k0/casperjs/issues/%s', '#'), + 'repo': ('https://github.com/n1k0/casperjs/%s', ''), +} diff --git a/vendor/casperjs/docs/credits.rst b/vendor/casperjs/docs/credits.rst new file mode 100755 index 0000000..f0131d5 --- /dev/null +++ b/vendor/casperjs/docs/credits.rst @@ -0,0 +1,64 @@ +Credits +======= + +Author +------ + +CasperJS is mainly developed by `Nicolas Perriault `_ on its free time. + +If you want to thank him and/or sponsor the development of CasperJS, please consider donating (see links in the sidebar). + +Contributors +------------ + +These people have contributed to CasperJS: + +- Brikou CARRE +- Thomas Parisot +- Han Yu +- Chris Lorenzo +- Victor Yap +- Rob Barreca +- Tyler Ritchie +- Nick Rabinowitz +- Pascal Borreli +- Dave Lee +- Andrew Childs +- Solomon White +- Reina Sweet +- Jan Schaumann +- Elmar Langholz +- Clochix +- Donovan Hutchinson +- Julien Moulin +- Michael Geers +- Jason Funk +- Vladimir Chizhov +- Jean-Philippe Serafin +- snkashis +- Rafael +- Andrew de Andrade +- Ben Lowery +- Chris Winters +- Christophe Benz +- Harrison Reiser +- Jan Pochyla +- Jan-Martin Fruehwacht +- Julian Gruber +- Justin Slattery +- Justine Tunney +- KaroDidi +- Leandro Boscariol +- Maisons du monde +- Marcel Duran +- Mathieu Agopian +- Mehdi Kabab +- Mikko Peltonen +- Rafael Garcia +- Raphaël Benitte +- Tim Bunce + +Logo +---- + +CasperJS logo designed by `Jeremy Forveille `_ diff --git a/vendor/casperjs/docs/debugging.rst b/vendor/casperjs/docs/debugging.rst new file mode 100755 index 0000000..6cbbb4f --- /dev/null +++ b/vendor/casperjs/docs/debugging.rst @@ -0,0 +1,111 @@ +.. _debugging: + +.. index:: Bugs, Debugging + +========= +Debugging +========= + +.. contents:: A few tips for debugging your casper scripts: + :local: + + +Use the :index:`verbose` mode +----------------------------- + +By default & by design, a ``Casper`` instance won't print anything to the console. This can be very limitating & frustrating when creating or debugging scripts, so a good practice is to always start coding a script using these :index:`settings`:: + + var casper = require('casper').create({ + verbose: true, + logLevel: "debug" + }); + +The ``verbose`` setting will tell Casper to write every logged message at the ``logLevel`` logging level onto the standard output, so you'll be able to trace every step made. + +.. warning:: + + Output will then be pretty verbose, and will potentially display sensitive informations onto the console. **Use with care on production.** + + +Hook in the deep using :index:`events` +-------------------------------------- + +:doc:`Events ` are a very powerful features of CasperJS, and you should probably give it a look if you haven't already. + +Some interesting events you may eventually use to debug your scripts: + +- The ``http.status.XXX`` event will be emitted everytime a resource is sent with the `HTTP code `_ corresponding to ``XXX``; +- The ``remote.alert`` everytime an ``alert()`` call is performed client-side; +- ``remote.message`` everytime a message is sent to the client-side console; +- ``step.added`` everytime a step is added to the stack; +- etc… + +Listening to an event is dead easy:: + + casper.on('http.status.404', function(resource) { + this.log('Hey, this one is 404: ' + resource.url, 'warning'); + }); + +Ensure to check the :ref:`full list ` of all the other available events. + + +.. _debugging_dump: + +Dump serialized values to the console +------------------------------------- + +Sometimes it's helpful to inspect a variable, especially Object contents. The :ref:`utils_dump() ` function can achieve just that:: + + require('utils').dump({ + foo: { + bar: 42 + }, + }); + +.. note:: + + :ref:`utils_dump() ` won't be able to serialize function nor complex cyclic structures though. + + +Localize yourself in modules +---------------------------- + +.. warning:: + + .. deprecated:: 1.1 + + As of 1.1, CasperJS uses PhantomJS' builtin `require` and won't expose the `__file__` variable anymore. + +If you're creating Casper modules, a cool thing to know is that there's a special built-in variable available in every module, ``__file__``, which contains the absolute path to current javascript file (the module file). + + +Name your closures +------------------ + +Probably one of the most easy but effective best practice, always name your closures: + +**Hard to track:** + +:: + + casper.start('http://foo.bar/', function() { + this.evaluate(function() { + // ... + }); + }); + +**Easier:** + +:: + + casper.start('http://foo.bar/', function afterStart() { + this.evaluate(function evaluateStuffAfterStart() { + // ... + }); + }); + +That way, everytime one is failing, its name will be printed out in the :index:`stack trace`, **so you can more easily locate it within your code**. + +.. note:: + + This one also applies for all your other Javascript works, of course ;) diff --git a/vendor/casperjs/docs/events-filters.rst b/vendor/casperjs/docs/events-filters.rst new file mode 100755 index 0000000..3299fa3 --- /dev/null +++ b/vendor/casperjs/docs/events-filters.rst @@ -0,0 +1,591 @@ +.. _events_filters: + +Events & filters +================ + +CasperJS provides an `event handler <#events>`_ very similar to the `nodejs `_' `one `_; actually it borrows most of its codebase. CasperJS also adds `filters <#filters>`_, which are basically ways to alter values asynchronously. + + +.. index:: ! events + +Events +------ + +Using events is pretty much straightforward if you're a node developer, or if you worked with any evented system before:: + + var casper = require('casper').create(); + + casper.on('resource.received', function(resource) { + casper.echo(resource.url); + }); + +Emitting you own events ++++++++++++++++++++++++ + +Of course you can emit your own events, using the ``Casper.emit()`` method:: + + var casper = require('casper').create(); + + // listening to a custom event + casper.on('google.loaded', function() { + this.echo('Google page title is ' + this.getTitle()); + }); + + casper.start('http://google.com/', function() { + // emitting a custom event + this.emit('google.loaded'); + }); + + casper.run(); + +.. _events_list: + +Events reference +++++++++++++++++ + +``back`` +~~~~~~~~ + +**Arguments:** ``None`` + +Emitted when the embedded browser is asked to go back a step in its history. + +``capture.saved`` +~~~~~~~~~~~~~~~~~ + +**Arguments:** ``targetFile`` + +Emitted when a :index:`screenshot` image has been captured. + +.. index:: click + +``click`` +~~~~~~~~~ + +**Arguments:** ``selector`` + +Emitted when the ``Casper.click()`` method has been called. + +``complete.error`` +~~~~~~~~~~~~~~~~~~ + +**Arguments:** ``error`` + +.. versionadded:: 1.1 + +Emitted when a complete callback has errored. + +By default, CasperJS doesn't listen to this event, you have to declare your own listeners by hand:: + + casper.on('complete.error', function(err) { + this.die("Complete callback has failed: " + err); + }); + +``die`` +~~~~~~~ + +**Arguments:** ``message, status`` + +Emitted when the ``Casper.die()`` method has been called. + +.. index:: download + +``downloaded.file`` +~~~~~~~~~~~~~~~~~~~ + +**Arguments:** ``targetPath`` + +Emitted when a file has been downloaded by :ref:`Casper.download() `; ``target`` will contain the path to the downloaded file. + +.. index:: error + +``error`` +~~~~~~~~~ + +**Arguments:** ``msg, backtrace`` + +.. versionadded:: 0.6.9 + +Emitted when an error hasn't been explicitly caught within the CasperJS/PhantomJS environment. Do basically what PhantomJS' ``onError()`` native handler does. + +.. index:: exit + +``exit`` +~~~~~~~~ + +**Arguments:** ``status`` + +Emitted when the ``Casper.exit()`` method has been called. + +.. index:: fill + +``fill`` +~~~~~~~~ + +**Arguments:** ``selector, vals, submit`` + +Emitted when a form is filled using the ``Casper.fill()`` method. + +``forward`` +~~~~~~~~~~~ + +**Arguments:** ``None`` + +Emitted when the embedded browser is asked to go forward a step in its history. + +.. index:: auth + +``http.auth`` +~~~~~~~~~~~~~ + +**Arguments:** ``username, password`` + +Emitted when http authentication parameters are set. + +.. index:: HTTP + +``http.status.[code]`` +~~~~~~~~~~~~~~~~~~~~~~ + +**Arguments:** ``resource`` + +Emitted when any given HTTP reponse is received with the status code specified by ``[code]``, eg.:: + + casper.on('http.status.404', function(resource) { + casper.echo(resource.url + ' is 404'); + }) + +``load.started`` +~~~~~~~~~~~~~~~~ + +**Arguments:** ``None`` + +Emitted when PhantomJS' ``WebPage.onLoadStarted`` event callback is called. + +``load.failed`` +~~~~~~~~~~~~~~~ + +**Arguments:** ``Object`` + +Emitted when PhantomJS' ``WebPage.onLoadFinished`` event callback has been called and failed. + +``load.finished`` +~~~~~~~~~~~~~~~~~ + +**Arguments:** ``status`` + +Emitted when PhantomJS' ``WebPage.onLoadFinished`` event callback is called. + +.. index:: log + +``log`` +~~~~~~~ + +**Arguments:** ``entry`` + +Emitted when the ``Casper.log()`` method has been called. The ``entry`` parameter is an Object like this:: + + { + level: "debug", + space: "phantom", + message: "A message", + date: "a javascript Date instance" + } + +..index:: click + +``mouse.click`` +~~~~~~~~~~~~~~~ + +**Arguments:** ``args`` + +Emitted when the mouse left-click something or somewhere. + +``mouse.down`` +~~~~~~~~~~~~~~ + +**Arguments:** ``args`` + +Emitted when the mouse presses on something or somewhere with the left button. + +``mouse.move`` +~~~~~~~~~~~~~~ + +**Arguments:** ``args`` + +Emitted when the mouse moves onto something or somewhere. + +``mouse.up`` +~~~~~~~~~~~~ + +**Arguments:** ``args`` + +Emitted when the mouse releases the left button over something or somewhere. + +``navigation.requested`` +~~~~~~~~~~~~~~~~~~~~~~~~ + +**Arguments:** ``url, navigationType, navigationLocked, isMainFrame`` + +.. versionadded:: 1.0 + +Emitted each time a navigation operation has been requested. Available navigation types are: ``LinkClicked``, ``FormSubmitted``, ``BackOrForward``, ``Reload``, ``FormResubmitted`` and ``Other``. + +.. index:: HTTP + +``open`` +~~~~~~~~ + +``location, settings`` + +Emitted when an HTTP request is sent. First callback arg is the location, second one is a request settings Object of the form:: + + { + method: "post", + data: "foo=42&chuck=norris" + } + +``page.created`` +~~~~~~~~~~~~~~~~ + +**Arguments:** ``page`` + +Emitted when PhantomJS' ``WebPage`` object used by CasperJS has been created. + +``page.error`` +~~~~~~~~~~~~~~ + +**Arguments:** ``message, trace`` + +Emitted when retrieved page leaves a Javascript error uncaught:: + + casper.on("page.error", function(msg, trace) { + this.echo("Error: " + msg, "ERROR"); + }); + +``page.initialized`` +~~~~~~~~~~~~~~~~~~~~ + +**Arguments:** ``WebPage`` + +Emitted when PhantomJS' ``WebPage`` object used by CasperJS has been initialized. + +.. index:: HTTP + +``page.resource.received`` +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +**Arguments:** ``response`` + +Emitted when the HTTP response corresponding to current required url has been received. + +.. index:: HTTP + +``page.resource.requested`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +**Arguments:** ``request`` + +Emitted when a new HTTP request is performed to open the required url. + +.. versionadded:: 1.1 + +**Arguments:** ``requestData, request`` + +You can also abort requests:: + + casper.on('page.resource.requested', function(requestData, request) { + if (requestData.url.indexOf('http://adserver.com') === 0) { + request.abort(); + } + }); + +``popup.created`` +~~~~~~~~~~~~~~~~~ + +**Arguments:** ``WebPage`` + +Emitted when a new window has been opened. + +``popup.loaded`` +~~~~~~~~~~~~~~~~ + +**Arguments:** ``WebPage`` + +Emitted when a new window has been loaded. + +``popup.closed`` +~~~~~~~~~~~~~~~~ + +**Arguments:** ``WebPage`` + +Emitted when a new opened window has been closed. + +``popup.created`` +~~~~~~~~~~~~~~~~~ + +**Arguments:** ``WebPage`` + +Emitted when a new window has been opened. + +``remote.alert`` +~~~~~~~~~~~~~~~~ + +**Arguments:** ``message`` + +Emitted when a remote ``alert()`` call has been performed. + +``remote.callback`` +~~~~~~~~~~~~~~~~~~~ + +**Arguments:** ``data`` + +Emitted when a remote `window.callPhantom(data) `_ call has been performed. + +``remote.message`` +~~~~~~~~~~~~~~~~~~ + +**Arguments:** ``msg`` + +Emitted when any remote console logging call has been performed. + +``resource.error`` +~~~~~~~~~~~~~~~~~~~~~ + +**Arguments:** ``resourceError`` + +Emitted when any requested resource fails to load properly. The received ``resourceError`` object has the following properties: + +- ``errorCode``: HTTP status code received +- ``url``: resource url + +``resource.received`` +~~~~~~~~~~~~~~~~~~~~~ + +**Arguments:** ``resource`` + +Emitted when any resource has been received. + +``resource.requested`` +~~~~~~~~~~~~~~~~~~~~~~ + +**Arguments:** ``request`` + +Emitted when any resource has been requested. + +``run.complete`` +~~~~~~~~~~~~~~~~ + +**Arguments:** ``None`` + +Emitted when the whole series of steps in the stack have been executed. + +``run.start`` +~~~~~~~~~~~~~ + +**Arguments:** ``None`` + +Emitted when ``Casper.run()`` is called. + +``starting`` +~~~~~~~~~~~~ + +**Arguments:** ``None`` + +Emitted when ``Casper.start()`` is called. + +``started`` +~~~~~~~~~~~ + +**Arguments:** ``None`` + +Emitted when Casper has been started using ``Casper.start()``. + +``step.added`` +~~~~~~~~~~~~~~ + +**Arguments:** ``step`` + +Emitted when a new navigation step has been added to the stack. + +``step.complete`` +~~~~~~~~~~~~~~~~~ + +**Arguments:** ``stepResult`` + +Emitted when a navigation step has been executed. + +``step.created`` +~~~~~~~~~~~~~~~~ + +**Arguments:** ``fn`` + +Emitted when a new navigation step has been created. + +``step.error`` +~~~~~~~~~~~~~~ + +**Arguments:** ``error`` + +.. versionadded:: 1.1 + +Emitted when a step function has errored. + +By default, CasperJS doesn't listen to this event, you have to declare your own listeners by hand:: + + casper.on('step.error', function(err) { + this.die("Step has failed: " + err); + }); + +``step.start`` +~~~~~~~~~~~~~~ + +**Arguments:** ``step`` + +Emitted when a navigation step has been started. + +``step.timeout`` +~~~~~~~~~~~~~~~~ + +**Arguments:** ``[step, timeout]`` + +Emitted when a navigation step has been executed. + +``timeout`` +~~~~~~~~~~~ + +**Arguments:** ``None`` + +Emitted when the execution time of the script has reached the ``Casper.options.timeout`` value. + +``url.changed`` +~~~~~~~~~~~~~~~ + +**Arguments:** ``url`` + +.. versionadded:: 1.0 + +Emitted each time the current page url changes. + +.. index:: viewport + +``viewport.changed`` +~~~~~~~~~~~~~~~~~~~~ + +**Arguments:** ``[width, height]`` + +Emitted when the viewport has been changed. + +``wait.done`` +~~~~~~~~~~~~~ + +**Arguments:** ``None`` + +Emitted when a ``Casper.wait()``\ *operation ends.* + +``wait.start`` +~~~~~~~~~~~~~~ + +**Arguments:** ``None`` + +Emitted when a ``Casper.wait()`` operation starts. + +``waitFor.timeout`` +~~~~~~~~~~~~~~~~~~~ + +**Arguments:** ``[timeout, details]`` + +Emitted when the execution time of a ``Casper.wait*()`` operation has exceeded the value of ``timeout``. + +``deatils`` is a property bag describing what was being waited on. For example, if ``waitForSelector`` timed out, ``details`` will have a ``selector`` string property that was the selector that did not show up in time. + + +.. index:: filters + +Filters +------- + +Filters allow you to alter some values asynchronously. Sounds obscure? Let's take a simple example and imagine you would like to alter every single url opened by CasperJS to append a ``foo=42`` query string parameter:: + + var casper = require('casper').create(); + + casper.setFilter('open.location', function(location) { + return /\?+/.test(location) ? location += "&foo=42" : location += "?foo=42"; + }); + +There you have it, every single requested url will have this appended. Let me bet you'll find far more interesting use cases than my silly one ;) + +Here'a the list of all available filters with their expected return value: + +Filters reference ++++++++++++++++++ + +.. index:: screenshot + +``capture.target_filename`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +**Arguments:** ``args`` + +**Return type:** ``String`` + +Allows to alter the value of the filename where a screen capture should be stored. + +``echo.message`` +~~~~~~~~~~~~~~~~ + +**Arguments:** ``message`` + +**Return type:** ``String`` + +Allows to alter every message written onto stdout. + +``log.message`` +~~~~~~~~~~~~~~~ + +**Arguments:** ``message`` + +**Return type:** ``String`` + +Allows to alter every log message. + +``open.location`` +~~~~~~~~~~~~~~~~~ + +**Arguments:** ``args`` + +**Return type:** ``String`` + +Allows to alter every url before it being opened. + +``page.confirm`` +~~~~~~~~~~~~~~~~ + +**Arguments:** ``message`` + +**Return type:** ``Boolean`` + +.. versionadded:: 1.0 + +Allows to react on a javascript ``confirm()`` call:: + + casper.setFilter("page.confirm", function(msg) { + return msg === "Do you like vbscript?" ? false : true; + }); + +``page.prompt`` +~~~~~~~~~~~~~~~ + +**Arguments:** ``message, value`` + +**Return type:** ``String`` + +.. versionadded:: 1.0 + +Allows to react on a javascript ``prompt()`` call:: + + casper.setFilter("page.prompt", function(msg, value) { + if (msg === "What's your name?") { + return "Chuck"; + } + }); diff --git a/vendor/casperjs/docs/extending.rst b/vendor/casperjs/docs/extending.rst new file mode 100755 index 0000000..2455a68 --- /dev/null +++ b/vendor/casperjs/docs/extending.rst @@ -0,0 +1,138 @@ +.. _extending: + +.. index:: extending, inheritance, prototype + +========= +Extending +========= + +Sometimes it can be convenient to add your own methods to a ``Casper`` object instance; you can easily do so as illustrated in the example below:: + + var casper = require('casper').create({ + verbose: true, + logLevel: "debug" + }); + + var links = { + 'http://edition.cnn.com/': 0, + 'http://www.nytimes.com/': 0, + 'http://www.bbc.co.uk/': 0, + 'http://www.guardian.co.uk/': 0 + }; + + casper.countLinks = function() { + return this.evaluate(function() { + return __utils__.findAll('a[href]').length; + }); + }; + + casper.renderJSON = function(what) { + return this.echo(JSON.stringify(what, null, ' ')); + }; + + casper.start(); + + casper.each(Object.keys(links), function(casper, link) { + this.thenOpen(link, function() { + links[link] = this.countLinks(); + }); + }); + + casper.run(function() { + this.renderJSON(links).exit(); + }); + +But that's just plain old *monkey-patching* the ``casper`` object, and you may probably want a more OO approach… That's where the ``inherits()`` function from the ``utils`` module and ported from `nodejs `_ comes handy:: + + var Casper = require('casper').Casper; + var utils = require('utils'); + var links = { + 'http://edition.cnn.com/': 0, + 'http://www.nytimes.com/': 0, + 'http://www.bbc.co.uk/': 0, + 'http://www.guardian.co.uk/': 0 + }; + + function Fantomas() { + Fantomas.super_.apply(this, arguments); + } + + // Let's make our Fantomas class extending the Casper one + // please note that at this point, CHILD CLASS PROTOTYPE WILL BE OVERRIDEN + utils.inherits(Fantomas, Casper); + + Fantomas.prototype.countLinks = function() { + return this.evaluate(function() { + return __utils__.findAll('a[href]').length; + }); + }; + + Fantomas.prototype.renderJSON = function(what) { + return this.echo(JSON.stringify(what, null, ' ')); + }; + + var fantomas = new Fantomas({ + verbose: true, + logLevel: "debug" + }); + + fantomas.start(); + + Object.keys(links).forEach(function(url) { + fantomas.thenOpen(url, function() { + links[url] = this.countLinks(); + }); + }); + + fantomas.run(function() { + this.renderJSON(links).exit(); + }); + +.. note:: + + The use of the ``super_`` child class property which becomes available once its parent has been defined using ``inherits()``; it contains a reference to the parent constructor. + + **Don't forget to call ``Casper``'s parent constructor!** + + Of course this approach is bit more verbose than the easy *monkey-patching* one, so please ensure you're not just overengineering stuff by subclassing the ``Casper`` class. + + +.. index:: coffeescript + +Using CoffeeScript +~~~~~~~~~~~~~~~~~~ + +If you're writing your casper scripts using `CoffeeScript `_, extending casper is getting a bit more straightforward: + +.. code-block:: coffeescript + + links = + 'http://edition.cnn.com/': 0 + 'http://www.nytimes.com/': 0 + 'http://www.bbc.co.uk/': 0 + 'http://www.guardian.co.uk/': 0 + + class Fantomas extends require('casper').Casper + countLinks: -> + @evaluate -> + __utils__.findAll('a').length + + renderJSON: (what) -> + @echo JSON.stringify what, null, ' ' + + fantomas = new Fantomas + loadImages: false + logLevel: "debug" + verbose: true + + fantomas.start() + + for url of links + do (url) -> + fantomas.thenOpen url, -> + links[url] = @countLinks() + + fantomas.run -> + @renderJSON links + @exit() + diff --git a/vendor/casperjs/docs/faq.rst b/vendor/casperjs/docs/faq.rst new file mode 100755 index 0000000..43c5a40 --- /dev/null +++ b/vendor/casperjs/docs/faq.rst @@ -0,0 +1,360 @@ +.. _faq: + +.. index:: FAQ, Help + +=== +FAQ +=== + +.. contents:: Here's a selection of the most frequently asked questions by CasperJS newcomers: + :local: + :backlinks: top + +.. index:: Node.js + +Is CasperJS a `node.js `_ library? +------------------------------------------------------ + +**No.** CasperJS is written on top of PhantomJS_, which is a node-independent Qt_/WebKit_ based library. If you try to run your CasperJS script with node, it just won't work out of the box. + +.. hint:: If you want to drive CasperJS from node, try `SpookyJS `_. + + +.. index:: Bugs, Contributing, error + +I'm stuck! I think there's a bug! What can I do? +------------------------------------------------ + +Before rage-tweeting: + +1. Read the `docs `_ +2. Check if an `issue `_ has been open about your problem already +3. Check you're running the `latest stable tag `_ +4. Check you're running the `latest version `_ of PhantomJS_ +5. Ask on the `project mailing list `_: + + a. try to post a reproducible, minimal test case + b. compare casperjs results with native phantomjs ones + c. if the problem also occurs with native phantomjs, ask on `phantomjs mailing list `_ + +6. Eventually, `file an issue `_. + + +.. index:: Testing + +The ``casper.test`` property is undefined, I can't write any test! +------------------------------------------------------------------ + +That's because as of 1.1, the ``casper.test`` property is only set to a :doc:`Tester ` instance when using the ``casperjs test`` subcommand. + +You may want to read the :doc:`testing documentation ` for more information. + + +.. index:: Code reuse + +I keep copy and pasting stuff in my test scripts, that's boring +--------------------------------------------------------------- + +Have a look at `this gist `_, it might help. + +Also, don't forget that CasperJS supports a `CommonJS-compliant module pattern `_ implementation. + +.. note:: + + CasperJS' implementation of ``require()`` differs a bit from the one provided by PhantomJS_, but I personnaly never really encountered any functional difference. + + +.. index:: Versionning + +What is the versioning policy of CasperJS? +------------------------------------------ + +Releases will follow the `SemVer standard `_; they +will be numbered with the follow format: + +.. code-block:: text + + ..[-] + +And constructed with the following guidelines: + +- Breaking backwards compatibility bumps the major +- New additions without breaking backwards compatibility bumps the minor +- Bug fixes and misc changes bump the patch +- Unstable, special and trunk versions will have a proper identifier + + +.. index:: jQuery + +Can I use jQuery with CasperJS? +------------------------------- + +Sure, you can use `jQuery `_, as every single other javascript library on Earth. + +A first solution is to inject it into the remote DOM environment by hand using the standard ``WebPage.injectJs()`` method:: + + casper.page.injectJs('/path/to/jquery.js'); + +If you need jQuery being available everytime, you can also make it being injected in every received response by setting the ``clientScripts`` option of CasperJS:: + + var casper = require('casper').create({ + clientScripts: ["includes/jquery.min.js"] + }); + +.. note:: + + You can't *inject* scripts using the HTTP protocol, you actually have to use a relative/absolute filesystem path to the script resource. + + +.. index:: Windows, Python, Ruby + +Can I use CasperJS without using the ``casperjs`` executable? +------------------------------------------------------------- + +Yes, you can call a CasperJS script directly with the ``phantomjs`` +executable, but if you do so, you must set the ``phantom.casperPath`` +property to the path where the library root is located on your system:: + + // casperscript.js + phantom.casperPath = '/path/to/casperjs'; + phantom.injectJs(phantom.casperPath + '/bin/bootstrap.js'); + + var casper = require('casper').create(); + // ... + +You can run such a script like any other standard PhantomJS_ script:: + + $ phantomjs casperscript.js + +**If you're on Windows**, this is the way you may manage to get casper +working the most easily:: + + phantom.casperPath = 'C:\\path\\to\\your\\repo\\lib\\casperjs-0.6.X'; + phantom.injectJs(phantom.casperPath + '\\bin\\bootstrap.js'); + + var casper = require('casper').create(); + + // do stuff + + +.. index:: HTTP + +How can I catch HTTP 404 and other status codes? +------------------------------------------------ + +You can define your own `HTTP status +code `_ handlers +by using the ``httpStatusHandlers`` option of the Casper object. You can +also catch other HTTP status codes as well, as demoed below:: + + var casper = require('casper').create(); + + casper.on('http.status.404', function(resource) { + this.echo('wait, this url is 404: ' + resource.url); + }); + + casper.on('http.status.500', function(resource) { + this.echo('woops, 500 error: ' + resource.url); + }); + + casper.start('http://mywebsite/404', function() { + this.echo('We suppose this url return an HTTP 404'); + }); + + casper.thenOpen('http://mywebsite/500', function() { + this.echo('We suppose this url return an HTTP 500'); + }); + + casper.run(function() { + this.echo('Done.').exit(); + }); + +.. hint:: + + Check out all the other cool :doc:`events ` you may use as well. + + +.. index:: log, Logging + +Where does CasperJS write its logfile? +-------------------------------------- + +Nowhere. CasperJS doesn't write logs on the filesystem. You have to implement this by yourself if needed. + + +.. index:: __utils__, AJAX + +What's this mysterious ``__utils__`` object? +-------------------------------------------- + +The ``__utils__`` object is actually a :ref:`ClientUtils object ` which have been automatically injected into the page DOM and is therefore alway available. + +So everytime to perform an :ref:`evaluate() ` call, you have this instance available to perform common operation like: + +- fetching nodes using CSS3 or XPath selectors, +- retrieving information about element properties (attributes, size, bounds, etc.), +- sending AJAX requests, +- triggering DOM events + +Check out the :doc:`whole API `. You even have :ref:`a bookmarklet ` to play around with this ``__utils__`` instance right within your browser console! + +.. note:: + + You're not obliged at all to use the ``__utils__`` instance in your scripts. It's just there because it's used by CasperJS internals. + + +.. index:: Step stack, Asynchronicity + +How does ``then()`` and the step stack work? +-------------------------------------------- + +Disclaimer This entry is based on an `answer I made on Stack Overflow `_. + +The ``then()`` method basically adds a new navigation step in a stack. A step is a javascript function which can do two different things: + +1. waiting for the previous step - if any - being executed +2. waiting for a requested url and related page to load + +Let's take a simple navigation scenario:: + + var casper = require('casper').create(); + + casper.start(); + + casper.then(function step1() { + this.echo('this is step one'); + }); + + casper.then(function step2() { + this.echo('this is step two'); + }); + + casper.thenOpen('http://google.com/', function step3() { + this.echo('this is step 3 (google.com is loaded)'); + }); + +You can print out all the created steps within the stack like this:: + + require('utils').dump(casper.steps.map(function(step) { + return step.toString(); + })); + +That gives:: + + $ casperjs test-steps.js + [ + "function step1() { this.echo('this is step one'); }", + "function step2() { this.echo('this is step two'); }", + "function _step() { this.open(location, settings); }", + "function step3() { this.echo('this is step 3 (google.com is loaded)'); }" + ] + +Notice the ``_step()`` function which has been added automatically by CasperJS to load the url for us; when the url is loaded, the next step available in the stack — which is ``step3()`` — is *then* called. + +When you have defined your navigation steps, ``run()`` executes them one by one sequentially:: + + casper.run(); + +.. note:: The callback/listener stuff is an implementation of the `Promise pattern `_. + +.. _faq_web_security: + +.. index:: Web security, download, CORS + +I'm having hard times downloading files using ``download()`` +------------------------------------------------------------ + +You should try to disable `web security`. Using the ``--web-security`` command line option: + +.. code-block:: text + + $ casperjs --web-security=no myscript.js + +Within code:: + + var casper = require('casper').create({ + pageSettings: { + webSecurityEnabled: false + } + }); + +Or anytime:: + + casper.page.settings.webSecurityEnabled = false; + +Is it possible to achieve parallel browsing using CasperJS? +----------------------------------------------------------- + +`Officially no `_, but you may want to try. + + +Can I access & manipulate DOM elements directly from the CasperJS environment? +------------------------------------------------------------------------------ + +No. Like in PhantomJS, you have to use :ref:`Casper#evaluate() ` to access actual page DOM and manipulate elements. + +For example, you **can't** do this:: + + // this won't work + casper.then(function() { + var titleNode = document.querySelector('h1'); + this.echo('Title is: ' + titleNode.textContent); + titleNode.textContent = 'New title'; + this.echo('Title is now: ' + titleNode.textContent); + }); + +You have to use the :ref:`Casper#evaluate() ` method in order to communicate with the page DOM:: + + // this will + casper.then(function() { + var titleText = this.evaluate(function() { + return document.querySelector('h1').textContent; + }); + this.echo('Title is: ' + titleText); + this.evaluate(function() { + document.querySelector('h1').textContent = 'New title'; + }); + this.echo('Title is now: ' + this.evaluate(function() { + return document.querySelector('h1').textContent; + })); + }); + +Of course, it's a whole lot more verbose, but Casper provides convenient methods to ease accessing elements properties, eg. :ref:`Casper#fetchText() ` and :ref:`Casper#getElementInfo() `:: + + // this will + casper.then(function() { + this.echo('Title is: ' + this.fetchText('h1')); + this.evaluate(function() { + document.querySelector('h1').textContent = 'New title'; + }); + this.echo('Element HTML is now: ' + this.getElementInfo('h1').html); + }); + +.. _faq_test_casper_instance: + +Why can't I create a new `casper` instance in a test environment? +----------------------------------------------------------------- + +The `casperjs test` :ref:`subcommand ` is a convenient utility which bootstraps and configures a :ref:`test environment ` for you, so a preconfigured `casper` object is already available in your test script when using this command. + +As of 1.1-beta3, you're prevented to override this preconfigured instance at this practice prevents the test runner to work properly. If you try to create a new casper instance in a test script, you'll get an error and CasperJS will exit with an error message with a link pointing to the documentation. + +One may argue this is mostly related to some hostorical bad design decision, and she might be true. This behavior is not likely exist anymore in a future 2.0. + +.. _faq_javascript: + +Okay, honestly, I'm stuck with Javascript. +------------------------------------------ + +Don't worry, you're not alone. Javascript is a great language, but it's far more difficult to master than one might expect at first look. + +Here are some great resources to get started efficiently with the language: + +- Learn and practice Javascript online at `Code Academy `_ +- `Eloquent Javascript `_ +- `JavaScript Enlightenment `_ (PDF) +- last, a `great tutorial on Advanced Javascript Techniques `_ by John Resig, the author of jQuery. If you master this one, you're almost done with the language. + +.. _PhantomJS: http://phantomjs.org/ +.. _Qt: http://qt.digia.com/ +.. _WebKit: http://www.webkit.org/ diff --git a/vendor/casperjs/docs/index.rst b/vendor/casperjs/docs/index.rst new file mode 100755 index 0000000..334dd7f --- /dev/null +++ b/vendor/casperjs/docs/index.rst @@ -0,0 +1,46 @@ +====================== +CasperJS documentation +====================== + +CasperJS_ is a navigation scripting & testing utility for the PhantomJS_ (WebKit) and SlimerJS_ (Gecko) headless browsers, written in Javascript. + +.. figure:: _static/images/casperjs-logo.png + :align: right + +.. toctree:: + :maxdepth: 2 + + installation + quickstart + cli + selectors + testing + modules/index + writing_modules + events-filters + logging + extending + debugging + faq + changelog + upgrading/index + credits + license + +You can also search the :ref:`genindex` if you're looking for something particular. + +.. index:: Community, Contributing, Help, Support + +Community +--------- + +- `get the code `_ and `contribute `_ +- join the `mailing list `_ +- check out `the ecosystem `_ +- follow `@casperjs\_org `_ on Twitter +- there's also a `Google+ account `_ (not much updated though) + + +.. _CasperJS: http://casperjs.org/ +.. _PhantomJS: http://phantomjs.org/ +.. _SlimerJS: http://slimerjs.org/ diff --git a/vendor/casperjs/docs/installation.rst b/vendor/casperjs/docs/installation.rst new file mode 100755 index 0000000..4766a50 --- /dev/null +++ b/vendor/casperjs/docs/installation.rst @@ -0,0 +1,187 @@ +.. _installation: +.. index:: Installation + +============ +Installation +============ + +CasperJS can be installed on Mac OSX, Windows and most Linuxes. + +Prerequisites +------------- + +.. index:: PhantomJS, Python, SlimerJS + +- PhantomJS_ 1.8.1 or greater. Installation instructions can be found `here `_ +- Python_ 2.6 or greater for ``casperjs`` in the ``bin/`` directory +- .NET Framework 3.5 or greater (or Mono_ 2.10.8 or greater) for ``casperjs.exe`` in the ``bin/`` directory + +.. versionadded:: 1.1 + +- **Experimental:** as of 1.1-beta1, SlimerJS_ 0.8 or greater to run your tests against Gecko (Firefox) instead of Webkit. To see PhantomJS API compatibility of SlimerJS, please `refer to this page `_. + +.. warning:: + + .. deprecated:: 1.1 + + The `Ruby `_ version of the ``casperjs`` executable also available in the ``rubybin/`` directory has been deprecated as of 1.1-beta, and is not compatible with SlimerJS_. + + The batch version of the ``casperjs`` executable also available in the ``batchbin/`` directory has been deprecated as of 1.1-beta, and is not compatible with SlimerJS_. + +.. index:: Homebrew + +Installing from Homebrew (OSX) +------------------------------ + +Installation of both PhantomJS and CasperJS can be achieved using Homebrew_, a popular package manager for Mac OS X. + +Above all, don't forget to update Formulaes:: + + $ brew update + +For the 1.1 development version (recommended):: + + $ brew install casperjs --devel + +For the 1.0.x stable version:: + + $ brew install casperjs + +If you have already installed casperjs and want to have the last release (stable|devel), use ``upgrade``:: + + $ brew upgrade casperjs + +Upgrade only update to the latest release branch (1.0.x|1.1-dev). + +.. index:: git + +Installing from git +------------------- + +Installation can be achieved using `git `_. The code is mainly hosted on `Github `_. + +From the master branch +~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: text + + $ git clone git://github.com/n1k0/casperjs.git + $ cd casperjs + $ ln -sf `pwd`/bin/casperjs /usr/local/bin/casperjs + +Once PhantomJS and CasperJS installed on your machine, you should obtain something like this: + +.. code-block:: text + + $ phantomjs --version + 1.8.1 + $ casperjs + CasperJS version 1.1.0-DEV at /Users/niko/Sites/casperjs, using phantomjs version 1.8.1 + # ... + +Or if SlimerJS is your thing: + +.. code-block:: text + + $ slimerjs --version + Innophi SlimerJS 0.8pre, Copyright 2012-2013 Laurent Jouanneau & Innophi + $ casperjs + CasperJS version 1.1.0-DEV at /Users/niko/Sites/casperjs, using slimerjs version 0.8.0 + +You are now ready to write your :doc:`first script `! + + +Installing from an archive +-------------------------- + +You can download tagged archives of CasperJS code: + +**Latest stable version:** + +- https://github.com/n1k0/casperjs/zipball/1.0.3 (zip) +- https://github.com/n1k0/casperjs/tarball/1.0.3 (tar.gz) + +**Latest development version (master branch):** + +- https://github.com/n1k0/casperjs/zipball/master (zip) +- https://github.com/n1k0/casperjs/tarball/master (tar.gz) + +Operations are then the same as with a git checkout. + + +.. index:: Windows + +CasperJS on Windows +------------------- + +Phantomjs installation additions +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +- Append ``";C:\phantomjs"`` to your ``PATH`` environment variable. +- Modify this path appropriately if you installed PhantomJS to a different location. + +Casperjs installation additions +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +**CasperJS, as of 1.1-beta3, ships with a .NET application so you don't need Python nor Ruby to use it.** + +.. versionadded:: 1.1-beta3 + +- Append ``";C:\casperjs\bin"`` to your ``PATH`` environment variable. +- Modify this path appropriately if you installed CasperJS to a different location. + +You can now run any regular casper scripts that way: + +.. code-block:: text + + C:> casperjs myscript.js + +Earlier versions of CasperJS +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +**CasperJS, as of 1.0.0-RC3, ships with a Batch script so you don't need Python nor Ruby to use it.** + +- Append ``";C:\casperjs\batchbin"`` to your ``PATH`` environment variable. +- Modify this path appropriately if you installed CasperJS to a different location. + +You can now run any regular casper scripts that way: + +.. code-block:: text + + C:> casperjs.bat myscript.js + +**Before 1.0.0-RC3, you had to setup your casper scripts that way::** + + phantom.casperPath = 'C:\\casperjs-1.1'; + phantom.injectJs(phantom.casperPath + '\\bin\\bootstrap.js'); + + var casper = require('casper').create(); + + // do stuff + +Run the script using the ``phantom.exe`` program: + +.. code-block:: text + + C:> phantomjs.exe myscript.js + +.. note:: + + .. versionadded:: 1.1-beta1 + + Windows users will get colorized output if ansicon_ is installed. + + +.. index:: Bugs, REPL + +Known Bugs & Limitations +------------------------ + +- Due to its asynchronous nature, CasperJS doesn't work well with `PhantomJS' REPL `_. + +.. _Homebrew: http://mxcl.github.com/homebrew/ +.. _PhantomJS: http://phantomjs.org/ +.. _Python: http://python.org/ +.. _SlimerJS: http://slimerjs.org/ +.. _ansicon: https://github.com/adoxa/ansicon +.. _Mono: http://www.mono-project.com/ diff --git a/vendor/casperjs/docs/license.rst b/vendor/casperjs/docs/license.rst new file mode 100755 index 0000000..ab826fb --- /dev/null +++ b/vendor/casperjs/docs/license.rst @@ -0,0 +1,29 @@ +.. _license: + +.. index:: Licensing + +======= +License +======= + +`CasperJS `_ is released under the terms of the +`MIT license `_. + +:: + + Copyright (c) 2011-{{year}} Nicolas Perriault + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. diff --git a/vendor/casperjs/docs/logging.rst b/vendor/casperjs/docs/logging.rst new file mode 100755 index 0000000..6864f32 --- /dev/null +++ b/vendor/casperjs/docs/logging.rst @@ -0,0 +1,69 @@ +.. _logging: + +.. index:: Logging, log levels + +======= +Logging +======= + +CasperJS allows logging using the :ref:`casper.log() ` method and these standard event levels: + +- ``debug`` +- ``info`` +- ``warning`` +- ``error`` + +Sample use:: + + var casper = require('casper').create(); + casper.log('plop', 'debug'); + casper.log('plip', 'warning'); + +.. index:: verbose + +Now, there are two things to distinguish: log *storage* and log *display*; by default CasperJS won't print the logs to the standard output. In order to do so, you must enable the ``verbose`` Casper option:: + + var casper = require('casper').create({ + verbose: true + }); + +Also, by default Casper is configured to filter logging which is under the ``error`` level; you can override this setting by configuring the ``logLevel`` option:: + + var casper = require('casper').create({ + verbose: true, + logLevel: 'debug' + }); + +You can also dump a JSON log of your Casper suite just by rendering the contents of the ``Casper.logs`` property:: + + var casper = require('casper').create({ + // ... + casper.run(function() { + require('utils').dump(this.logs); + this.exit(); + }); + +Last, if you print log messages to the standard output using the ``verbose`` option, you'll get some fancy colors:: + + var casper = require('casper').create({ + verbose: true, + logLevel: 'debug' + }) + casper.log('this is a debug message', 'debug'); + casper.log('and an informative one', 'info'); + casper.log('and a warning', 'warning'); + casper.log('and an error', 'error'); + casper.exit(); + +This will give the following output: + +.. figure:: _static/images/logoutput.png + :align: center + :alt: image + + image + + +.. hint:: + + CasperJS doesn't write logs on the filesystem. You have to implement this by yourself if needed. diff --git a/vendor/casperjs/docs/modules/casper.rst b/vendor/casperjs/docs/modules/casper.rst new file mode 100755 index 0000000..bdafbf4 --- /dev/null +++ b/vendor/casperjs/docs/modules/casper.rst @@ -0,0 +1,2289 @@ +.. _casper_module: + +===================== +The ``casper`` module +===================== + +.. index:: Casper + +The ``Casper`` class +++++++++++++++++++++ + +The easiest way to get a casper instance is to use the module's ``create()`` method:: + + var casper = require('casper').create(); + +But you can also retrieve the main Function and instantiate it by yourself:: + + var casper = new require('casper').Casper(); + +.. hint:: + + Also, check out :doc:`how to extend Casper with your own methods <../extending>`. + +Both the ``Casper`` constructor and the ``create()`` function accept a single ``options`` argument which is a standard javascript object:: + + var casper = require('casper').create({ + verbose: true, + logLevel: "debug" + }); + +.. _casper_options: + +.. index:: Casper options, options + +``Casper.options`` +++++++++++++++++++ + +An ``options`` object can be passed to the ``Casper`` constructor, eg.:: + + var casper = require('casper').create({ + clientScripts: [ + 'includes/jquery.js', // These two scripts will be injected in remote + 'includes/underscore.js' // DOM on every request + ], + pageSettings: { + loadImages: false, // The WebPage instance used by Casper will + loadPlugins: false // use these settings + }, + logLevel: "info", // Only "info" level messages will be logged + verbose: true // log messages will be printed out to the console + }); + +You can also alter options at runtime:: + + var casper = require('casper').create(); + casper.options.waitTimeout = 1000; + +The whole list of available options is detailed below. + +.. index:: Client scripts + +.. _casper_option_clientscripts: + +``clientScripts`` +------------------------------------------------------------------------------- + +**Type:** ``Array`` + +**Default:** ``[]`` + +A collection of script filepaths to include in every page loaded + +.. index:: exit, error + +``exitOnError`` +------------------------------------------------------------------------------- + +**Type:** ``Boolean`` + +**Default:** ``true`` + +Sets if CasperJS must exit when an uncaught error has been thrown by the script. + +.. index:: HTTP + +``httpStatusHandlers`` +------------------------------------------------------------------------------- + +**Type:** ``Object`` + +**Default:** ``{}`` + +A javascript Object containing functions to call when a requested resource has a given HTTP status code. A dedicated sample is provided as an example. + +.. index:: Logging + +``logLevel`` +------------------------------------------------------------------------------- + +**Type:** ``String`` + +**Default:** ``"error"`` + +Logging level (see the logging section for more information) + +``onAlert`` +------------------------------------------------------------------------------- + +**Type:** ``Function`` + +**Default:** ``null`` + +A function to be called when a javascript alert() is triggered + +``onDie`` +------------------------------------------------------------------------------- + +**Type:** ``Function`` + +**Default:** ``null`` + +A function to be called when Casper#die() is called + +.. index:: error, Error handling + +``onError`` +------------------------------------------------------------------------------- + +**Type:** ``Function`` + +**Default:** ``null`` + +A function to be called when an "error" level event occurs + +.. index:: error, Error handling + +``onLoadError`` +------------------------------------------------------------------------------- + +**Type:** ``Function`` + +**Default:** ``null`` + +A function to be called when a requested resource cannot be loaded + +``onPageInitialized`` +------------------------------------------------------------------------------- + +**Type:** ``Function`` + +**Default:** ``null`` + +A function to be called after ``WebPage`` instance has been initialized + +.. index:: HTTP + +``onResourceReceived`` +------------------------------------------------------------------------------- + +**Type:** ``Function`` + +**Default:** ``null`` + +Proxy method for PhantomJS' ``WebPage#onResourceReceived()`` callback, but the current Casper instance is passed as first argument. + +.. index:: HTTP + +``onResourceRequested`` +------------------------------------------------------------------------------- + +**Type:** ``Function`` + +**Default:** ``null`` + +Proxy method for PhantomJS' WebPage#onResourceRequested() callback, but the current Casper instance is passed as first argument. + +.. index:: Step stack + +``onStepComplete`` +------------------------------------------------------------------------------- + +**Type:** ``Function`` + +**Default:** ``null`` + +A function to be executed when a step function execution is finished. + +.. index:: Step stack, Error handling, timeout + +``onStepTimeout`` +------------------------------------------------------------------------------- + +**Type:** ``Function`` + +**Default:** ``Function`` + +A function to be executed when a step function execution time exceeds the value of the stepTimeout option, if any has been set. + +By default, on timeout the script will exit displaying an error, except in test environment where it will just add a failure to the suite results. + +.. index:: Error handling, timeout + +``onTimeout`` +------------------------------------------------------------------------------- + +**Type:** ``Function`` + +**Default:** ``Function`` + +A function to be executed when script execution time exceeds the value of the timeout option, if any has been set. + +By default, on timeout the script will exit displaying an error, except in test environment where it will just add a failure to the suite results. + +.. index:: Error handling, timeout + +``onWaitTimeout`` +------------------------------------------------------------------------------- + +**Type:** ``Function`` + +**Default:** ``Function`` + +A function to be executed when a ``waitFor*`` function execution time exceeds the value of the waitTimeout option, if any has been set. + +By default, on timeout the script will exit displaying an error, except in test environment where it will just add a failure to the suite results. + +``page`` +------------------------------------------------------------------------------- + +**Type:** ``WebPage`` + +**Default:** ``null`` + +An existing PhantomJS ``WebPage`` instance + +.. index:: settings, PhantomJS, SSL, auth, XSS + +``pageSettings`` +------------------------------------------------------------------------------- + +**Type:** ``Object`` + +**Default:** ``{}`` + +PhantomJS's WebPage settings object. Available settings are: + +- ``javascriptEnabled`` defines whether to execute the script in the page or not (default to ``true``) +- ``loadImages`` defines whether to load the inlined images or not +- ``loadPlugins`` defines whether to load NPAPI plugins (Flash, Silverlight, …) or not +- ``localToRemoteUrlAccessEnabled`` defines whether local resource (e.g. from file) can access remote URLs or not (default to ``false``) +- ``userAgent`` defines the user agent sent to server when the web page requests resources +- ``userName`` sets the user name used for HTTP authentication +- ``password`` sets the password used for HTTP authentication +- ``XSSAuditingEnabled`` defines whether load requests should be monitored for cross-site scripting attempts (default to ``false``) + +.. index:: Remote scripts + +``remoteScripts`` +------------------------------------------------------------------------------- + +**Type:** ``Array`` + +**Default:** ``[]`` + +.. versionadded:: 1.0 + +A collection of remote script urls to include in every page loaded + +.. index:: Logging + +``safeLogs`` +------------------------------------------------------------------------------- + +**Type:** ``Boolean`` + +**Default:** ``true`` + +.. versionadded:: 1.0 + +When this option is set to true — which is the default, any password information entered in will be obfuscated in log messages. Set safeLogs to false to disclose passwords in plain text (not recommended). + +.. index:: Step stack, timeout + +``silentErrors`` +------------------------------------------------------------------------------- + +**Type:** ``Boolean`` + +**Default:** ``false`` + +When this option is enabled, caught step errors are not thrown (though related events are still emitted). Mostly used internally in a testing context. + +.. index:: timeout + +``stepTimeout`` +------------------------------------------------------------------------------- + +**Type:** ``Number`` + +**Default:** ``null`` + +Max step timeout in milliseconds; when set, every defined step function will have to execute before this timeout value has been reached. You can define the onStepTimeout() callback to catch such a case. By default, the script will die() with an error message. + +.. index:: timeout + +``timeout`` +------------------------------------------------------------------------------- + +**Type:** ``Number`` + +**Default:** ``null`` + +Max timeout in milliseconds + +.. index:: verbose + +``verbose`` +------------------------------------------------------------------------------- + +**Type:** ``Boolean`` + +**Default:** ``false`` + +Realtime output of log messages + +.. index:: viewport + +``viewportSize`` +------------------------------------------------------------------------------- + +**Type:** ``Object`` + +**Default:** ``null`` + +Viewport size, eg. ``{width: 800, height: 600}`` + +.. note:: + + PhantomJS ships with a default viewport of 400x300, and CasperJS won't override it by default. + +.. index:: timeout + +``retryTimeout`` +------------------------------------------------------------------------------- + +**Type:** ``Number`` + +**Default:** ``100`` + +Default delay between attempts, for ``wait*`` family functions. + +``waitTimeout`` +------------------------------------------------------------------------------- + +**Type:** ``Number`` + +**Default:** ``5000`` + +Default wait timeout, for ``wait*`` family functions. + + +``Casper`` prototype +++++++++++++++++++++ + +``back()`` +------------------------------------------------------------------------------- + +**Signature:** ``back()`` + +Moves back a step in browser's history:: + + casper.start('http://foo.bar/1') + casper.thenOpen('http://foo.bar/2'); + casper.thenOpen('http://foo.bar/3'); + casper.back(); + casper.run(function() { + console.log(this.getCurrentUrl()); // 'http://foo.bar/2' + }); + +Also have a look at `forward()`_. + +.. _casper_base64encode: + +.. index:: Base64 + +``base64encode()`` +------------------------------------------------------------------------------- + +**Signature:** ``base64encode(String url [, String method, Object data])`` + +Encodes a resource using the base64 algorithm synchronously using +client-side XMLHttpRequest. + +.. note:: + + We cannot use ``window.btoa()`` because it fails miserably in the version of WebKit shipping with PhantomJS. + +Example: retrieving google logo image encoded in base64:: + + var base64logo = null; + casper.start('http://www.google.fr/', function() { + base64logo = this.base64encode('http://www.google.fr/images/srpr/logo3w.png'); + }); + + casper.run(function() { + this.echo(base64logo).exit(); + }); + +You can also perform an HTTP POST request to retrieve the contents to +encode:: + + var base64contents = null; + casper.start('http://domain.tld/download.html', function() { + base64contents = this.base64encode('http://domain.tld/', 'POST', { + param1: 'foo', + param2: 'bar' + }); + }); + + casper.run(function() { + this.echo(base64contents).exit(); + }); + +.. index:: bypass, Step stack + +``bypass()`` +------------------------------------------------------------------------------- + +**Signature:** ``bypass(Numbr nb)`` + +.. versionadded:: 1.1 + +Bypasses a given number of defined navigation steps:: + + casper.start(); + casper.then(function() { + // This step will be executed + }); + casper.then(function() { + this.bypass(2); + }); + casper.then(function() { + // This test won't be executed + }); + casper.then(function() { + // Nor this one + }); + casper.run(); + +.. _casper_click: + +.. index:: click + +``click()`` +------------------------------------------------------------------------------- + +**Signature:** ``click(String selector)`` + +Performs a click on the element matching the provided :doc:`selector expression <../selectors>`. The method tries two strategies sequentially: + +1. trying to trigger a MouseEvent in Javascript +2. using native QtWebKit event if the previous attempt failed + +Example:: + + casper.start('http://google.fr/'); + + casper.thenEvaluate(function(term) { + document.querySelector('input[name="q"]').setAttribute('value', term); + document.querySelector('form[name="f"]').submit(); + }, 'CasperJS'); + + casper.then(function() { + // Click on 1st result link + this.click('h3.r a'); + }); + + casper.then(function() { + console.log('clicked ok, new location is ' + this.getCurrentUrl()); + }); + + casper.run(); + +.. index:: click + +``clickLabel()`` +------------------------------------------------------------------------------- + +**Signature:** ``clickLabel(String label[, String tag])`` + +.. versionadded:: 0.6.1 + +Clicks on the first DOM element found containing ``label`` text. Optionaly ensures that the element node name is ``tag``:: + + // My link is beautiful + casper.then(function() { + this.clickLabel('My link is beautiful', 'a'); + }); + + // + casper.then(function() { + this.clickLabel('But my button is sexier', 'button'); + }); + +.. index:: screenshot + +``capture()`` +------------------------------------------------------------------------------- + +**Signature:** ``capture(String targetFilepath, [Object clipRect, Object imgOptions])`` + +Proxy method for PhantomJS' ``WebPage#render``. Adds a ``clipRect`` parameter for automatically setting page ``clipRect`` setting and reverts it back once done:: + + casper.start('http://www.google.fr/', function() { + this.capture('google.png', { + top: 100, + left: 100, + width: 500, + height: 400 + }); + }); + + casper.run(); + +.. versionadded:: 1.1 + +The ``imgOptions`` object allows to specify two options: + +- ``format`` to set the image format manually, avoiding relying on the filename +- ``quality`` to set the image quality, from 1 to 100 + +Example:: + + casper.start('http://foo', function() { + this.capture('foo', undefined, { + format: 'jpg', + quality: 75 + }); + }); + +.. index:: screenshot, Base64 + +``captureBase64()`` +------------------------------------------------------------------------------- + +**Signature:** ``captureBase64(String format[, Mixed area])`` + +.. versionadded:: 0.6.5 + +Computes the `Base64 `_ representation of a binary image capture of the current page, or an area within the page, in a given format. + +Supported image formats are ``bmp``, ``jpg``, ``jpeg``, ``png``, ``ppm``, ``tiff``, ``xbm`` and ``xpm``. + +The ``area`` argument can be either of the following types: + +- ``String``: area is a CSS3 selector string, eg. ``div#plop form[name="form"] input[type="submit"]`` +- ``clipRect``: area is a clipRect object, eg. ``{"top":0,"left":0,"width":320,"height":200}`` +- ``Object``: area is a :doc:`selector object <../selectors>`, eg. an XPath selector + +Example:: + + casper.start('http://google.com', function() { + // selector capture + console.log(this.captureBase64('png', '#lga')); + // clipRect capture + console.log(this.captureBase64('png', { + top: 0, + left: 0, + width: 320, + height: 200 + })); + // whole page capture + console.log(this.captureBase64('png')); + }); + + casper.run(); + +.. _casper_captureselector: + +.. index:: screenshot + +``captureSelector()`` +------------------------------------------------------------------------------- + +**Signature:** ``captureSelector(String targetFile, String selector [, Object imgOptions])`` + +Captures the page area containing the provided selector and saves it to ``targetFile``:: + + casper.start('http://www.weather.com/', function() { + this.captureSelector('weather.png', '#wx-main'); + }); + + casper.run(); + +.. versionadded:: 1.1 + +The ``imgOptions`` object allows to specify two options: + +- ``format`` to set the image format manually, avoiding relying on the target filename +- ``quality`` to set the image quality, from 1 to 100 + +``clear()`` +------------------------------------------------------------------------------- + +**Signature:** ``clear()`` + +.. versionadded:: 0.6.5 + +Clears the current page execution environment context. Useful to avoid having previously loaded DOM contents being still active. + +Think of it as a way to stop javascript execution within the remote DOM environment:: + + casper.start('http://www.google.fr/', function() { + this.clear(); // javascript execution in this page has been stopped + }); + + casper.then(function() { + // ... + }); + + casper.run(); + +.. index:: Debugging + +``debugHTML()`` +------------------------------------------------------------------------------- + +**Signature:** ``debugHTML([String selector, Boolean outer])`` + +Outputs the results of `getHTML()`_ directly to the console. It takes the same arguments as ``getHTML()``. + +.. index:: Debugging + +``debugPage()`` +------------------------------------------------------------------------------- + +**Signature:** ``debugPage()`` + +Logs the textual contents of the current page directly to the standard output, for debugging purpose:: + + casper.start('http://www.google.fr/', function() { + this.debugPage(); + }); + + casper.run(); + +``die()`` +------------------------------------------------------------------------------- + +**Signature:** ``die(String message[, int status])`` + +Exits phantom with a logged error message and an optional exit status code:: + + casper.start('http://www.google.fr/', function() { + this.die("Fail.", 1); + }); + + casper.run(); + +.. _casper_download: + +.. index:: download + +``download()`` +------------------------------------------------------------------------------- + +**Signature:** ``download(String url, String target[, String method, Object data])`` + +Saves a remote resource onto the filesystem. You can optionally set the HTTP method using the ``method`` argument, and pass request arguments through the ``data`` object (see `base64encode()`_):: + + casper.start('http://www.google.fr/', function() { + var url = 'http://www.google.fr/intl/fr/about/corporate/company/'; + this.download(url, 'google_company.html'); + }); + + casper.run(function() { + this.echo('Done.').exit(); + }); + +.. note:: + + If you have some troubles downloading files, try to :ref:`disable web security `. + +``each()`` +------------------------------------------------------------------------------- + +**Signature:** ``each(Array array, Function fn)`` + +Iterates over provided array items and execute a callback:: + + var links = [ + 'http://google.com/', + 'http://yahoo.com/', + 'http://bing.com/' + ]; + + casper.start().each(links, function(self, link) { + self.thenOpen(link, function() { + this.echo(this.getTitle()); + }); + }); + + casper.run(); + +.. hint:: + + Have a look at the `googlematch.js `_ sample script for a concrete use case. + +``eachThen()`` +------------------------------------------------------------------------------- + +**Signature:** ``eachThen(Array array, Function then)`` + +.. versionadded:: 1.1 + +Iterates over provided array items and adds a step to the stack with current data attached to it:: + + casper.start().eachThen([1, 2, 3], function(response) { + this.echo(response.data); + }).run(); + +Here's an example for opening an array of urls:: + + var casper = require('casper').create(); + var urls = ['http://google.com/', 'http://yahoo.com/']; + + casper.start().eachThen(urls, function(response) { + this.thenOpen(response.data, function(response) { + console.log('Opened', response.url); + }); + }); + + casper.run(); + +.. note:: + + Current item will be stored in the ``response.data`` property. + +.. _casper_echo: + +.. index:: echo, Printing + +``echo()`` +------------------------------------------------------------------------------- + +**Signature:** ``echo(String message[, String style])`` + +Prints something to stdout, optionally with some fancy color (see the :ref:`colorizer module ` for more information):: + + casper.start('http://www.google.fr/', function() { + this.echo('Page title is: ' + this.evaluate(function() { + return document.title; + }), 'INFO'); // Will be printed in green on the console + }); + + casper.run(); + +.. index:: evaluate, DOM + +.. _casper_evaluate: + +``evaluate()`` +------------------------------------------------------------------------------- + +**Signature:** ``evaluate(Function fn[, arg1[, arg2[, …]]])`` + +Basically `PhantomJS' WebPage#evaluate `_ equivalent. Evaluates an expression **in the current page DOM context**:: + + casper.evaluate(function(username, password) { + document.querySelector('#username').value = username; + document.querySelector('#password').value = password; + document.querySelector('#submit').click(); + }, 'sheldon.cooper', 'b4z1ng4'); + +.. note:: + + For filling and submitting forms, rather use the `fill()`_ method. + +.. warning:: + + The pre-1.0 way of passing arguments using an object has been kept for BC purpose, though it may `not work in some case `_; so you're encouraged to use the method described above. + +.. topic:: Understanding ``evaluate()`` + + The concept behind this method is probably the most difficult to understand when discovering CasperJS. As a reminder, think of the ``evaluate()`` method as a *gate* between the CasperJS environment and the one of the page you have opened; everytime you pass a closure to ``evaluate()``, you're entering the page and execute code as if you were using the browser console. + + Here's a quickly drafted diagram trying to basically explain the separation of concerns: + + .. figure:: ../_static/images/evaluate-diagram.png + :align: center + +``evaluateOrDie()`` +------------------------------------------------------------------------------- + +**Signature:** ``evaluateOrDie(Function fn[, String message])`` + +Evaluates an expression within the current page DOM and ``die()`` if it returns anything but ``true``:: + + casper.start('http://foo.bar/home', function() { + this.evaluateOrDie(function() { + return /logged in/.match(document.title); + }, 'not authenticated'); + }); + + casper.run(); + +.. index:: exit + +``exit()`` +------------------------------------------------------------------------------- + +**Signature:** ``exit([int status])`` + +Exits PhantomJS with an optional exit status code. + +.. index:: DOM + +``exists()`` +------------------------------------------------------------------------------- + +**Signature:** ``exists(String selector)`` + +Checks if any element within remote DOM matches the provided :doc:`selector <../selectors>`:: + + casper.start('http://foo.bar/home', function() { + if (this.exists('#my_super_id')) { + this.echo('found #my_super_id', 'INFO'); + } else { + this.echo('#my_super_id not found', 'ERROR'); + } + }); + + casper.run(); + +.. _casper_fetchtext: + +``fetchText()`` +------------------------------------------------------------------------------- + +**Signature:** ``fetchText(String selector)`` + +Retrieves text contents matching a given :doc:`selector expression <../selectors>`. If you provide one matching more than one element, their textual contents will be concatenated:: + + casper.start('http://google.com/search?q=foo', function() { + this.echo(this.fetchText('h3')); + }).run(); + +``forward()`` +------------------------------------------------------------------------------- + +**Signature:** ``forward()`` + +Moves a step forward in browser's history:: + + casper.start('http://foo.bar/1') + casper.thenOpen('http://foo.bar/2'); + casper.thenOpen('http://foo.bar/3'); + casper.back(); // http://foo.bar/2 + casper.back(); // http://foo.bar/1 + casper.forward(); // http://foo.bar/2 + casper.run(); + +Also have a look at `back()`_. + +.. _casper_log: + +.. index:: Logging + +``log()`` +------------------------------------------------------------------------------- + +**Signature:** ``log(String message[, String level, String space])`` + +Logs a message with an optional level in an optional space. Available levels are ``debug``, ``info``, ``warning`` and ``error``. A space is a kind of namespace you can set for filtering your logs. By default, Casper logs messages in two distinct spaces: ``phantom`` and ``remote``, to distinguish what happens in the PhantomJS environment from the remote one:: + + casper.start('http://www.google.fr/', function() { + this.log("I'm logging an error", "error"); + }); + + casper.run(); + +.. _casper_fill: + +.. index:: Form + +``fill()`` +------------------------------------------------------------------------------- + +**Signature:** ``fill(String selector, Object values[, Boolean submit])`` + +Fills the fields of a form with given values and optionally submits it. Fields +are referenced by their ``name`` attribute. + +.. versionchanged:: 1.1 To use :doc:`CSS3 or XPath selectors <../selectors>` instead, check the `fillSelectors()`_ and `fillXPath()`_ methods. + +Example with this sample html form: + +.. code-block :: html + +
    + + + Mr + Mrs + + + + Receive a copy + +
    + +A script to fill and submit this form:: + + casper.start('http://some.tld/contact.form', function() { + this.fill('form#contact-form', { + 'subject': 'I am watching you', + 'content': 'So be careful.', + 'civility': 'Mr', + 'name': 'Chuck Norris', + 'email': 'chuck@norris.com', + 'cc': true, + 'attachment': '/Users/chuck/roundhousekick.doc' + }, true); + }); + + casper.then(function() { + this.evaluateOrDie(function() { + return /message sent/.test(document.body.innerText); + }, 'sending message failed'); + }); + + casper.run(function() { + this.echo('message sent').exit(); + }); + +.. warning:: + + 1. The ``fill()`` method currently can't fill **file fields using XPath selectors**; PhantomJS natively only allows the use of CSS3 selectors in its ``uploadFile()`` method, hence this limitation. + 2. Please Don't use CasperJS nor PhantomJS to send spam, or I'll be calling the Chuck. More seriously, please just don't. + +``fillSelectors()`` +------------------------------------------------------------------------------- + +**Signature:** ``fillSelectors(String selector, Object values[, Boolean submit])`` + +.. versionadded:: 1.1 + +Fills form fields with given values and optionally submits it. Fields +are referenced by ``CSS3`` selectors:: + + casper.start('http://some.tld/contact.form', function() { + this.fillSelectors('form#contact-form', { + 'input[name="subject"]': 'I am watching you', + 'input[name="content"]': 'So be careful.', + 'input[name="civility"]': 'Mr', + 'input[name="name"]': 'Chuck Norris', + 'input[name="email"]': 'chuck@norris.com', + 'input[name="cc"]': true, + 'input[name="attachment"]': '/Users/chuck/roundhousekick.doc' + }, true); + }); + + +``fillXPath()`` +------------------------------------------------------------------------------- + +**Signature:** ``fillXPath(String selector, Object values[, Boolean submit])`` + +.. versionadded:: 1.1 + +Fills form fields with given values and optionally submits it. While the ``form`` element is always referenced by a CSS3 selector, fields are referenced by ``XPath`` selectors:: + + casper.start('http://some.tld/contact.form', function() { + this.fillXPath('form#contact-form', { + '//input[@name="subject"]': 'I am watching you', + '//input[@name="content"]': 'So be careful.', + '//input[@name="civility"]': 'Mr', + '//input[@name="name"]': 'Chuck Norris', + '//input[@name="email"]': 'chuck@norris.com', + '//input[@name="cc"]': true, + }, true); + }); + +.. warning:: + + The ``fillXPath()`` method currently can't fill **file fields using XPath selectors**; PhantomJS natively only allows the use of CSS3 selectors in its ``uploadFile()`` method, hence this limitation. + +.. index:: URL + +``getCurrentUrl()`` +------------------------------------------------------------------------------- + +**Signature:** ``getCurrentUrl()`` + +Retrieves current page URL. Note that the url will be url-decoded:: + + casper.start('http://www.google.fr/', function() { + this.echo(this.getCurrentUrl()); // "http://www.google.fr/" + }); + + casper.run(); + +.. index:: DOM + +``getElementAttribute()`` +------------------------------------------------------------------------------- + +**Signature:** ``getElementAttribute(String selector, String attribute)`` + +.. versionadded:: 1.0 + +Retrieves the value of an attribute on the first element matching the provided :doc:`selector <../selectors>`:: + + var casper = require('casper').create(); + + casper.start('http://www.google.fr/', function() { + require('utils').dump(this.getElementAttribute('div[title="Google"]', 'title')); // "Google" + }); + + casper.run(); + +.. index:: DOM + +``getElementsAttribute()`` +------------------------------------------------------------------------------- + +**Signature:** ``getElementsAttribute(String selector, String attribute)`` + +.. versionadded:: 1.1 + +Retrieves the values of an attribute on each element matching the provided :doc:`selector <../selectors>`:: + + var casper = require('casper').create(); + + casper.start('http://www.google.fr/', function() { + require('utils').dump(this.getElementsAttribute('div[title="Google"]', 'title')); // "['Google']" + }); + + casper.run(); + +.. index:: DOM + +``getElementBounds()`` +------------------------------------------------------------------------------- + +**Signature:** ``getElementBounds(String selector)`` + +Retrieves boundaries for a DOM element matching the provided :doc:`selector <../selectors>`. + +It returns an Object with four keys: ``top``, ``left``, ``width`` and ``height``, or ``null`` if the selector doesn't exist:: + + var casper = require('casper').create(); + + casper.start('http://www.google.fr/', function() { + require('utils').dump(this.getElementBounds('div[title="Google"]')); + }); + + casper.run(); + +This will output something like:: + + { + "height": 95, + "left": 352, + "top": 16, + "width": 275 + } + +.. index:: DOM + +``getElementsBounds()`` +------------------------------------------------------------------------------- + +**Signature:** ``getElementsBounds(String selector)`` + +.. versionadded:: 1.0 + +Retrieves a list of boundaries for all DOM elements matching the provided :doc:`selector <../selectors>`. + +It returns an array of objects with four keys: ``top``, ``left``, ``width`` and ``height`` (see `getElementBounds()`_). + +.. _casper_getelementinfo: + +.. index:: DOM + +``getElementInfo()`` +------------------------------------------------------------------------------- + +**Signature:** ``getElementInfo(String selector)`` + +.. versionadded:: 1.0 + +Retrieves information about the first element matching the provided :doc:`selector <../selectors>`:: + + casper.start('http://google.fr/', function() { + require('utils').dump(this.getElementInfo('#hplogo')); + }); + +Gives something like:: + + { + "attributes": { + "align": "left", + "dir": "ltr", + "id": "hplogo", + "onload": "window.lol&&lol()", + "style": "height:110px;width:276px;background:url(/images/srpr/logo1w.png) no-repeat", + "title": "Google" + }, + "height": 110, + "html": "
    France
    ", + "nodeName": "div", + "tag": "
    France
    ", + "text": "France\n", + "visible": true, + "width": 276, + "x": 62, + "y": 76 + } + +.. index:: DOM + +``getElementsInfo()`` +------------------------------------------------------------------------------- + +**Signature:** ``getElementsInfo(String selector)`` + +.. versionadded:: 1.1 + +Retrieves information about all elements matching the provided :doc:`selector <../selectors>`:: + + casper.start('http://google.fr/', function() { + require('utils').dump(this.getElementsInfo('#hplogo')); + }); + +Gives something like:: + + [ + { + "attributes": { + "align": "left", + "dir": "ltr", + "id": "hplogo", + "onload": "window.lol&&lol()", + "style": "height:110px;width:276px;background:url(/images/srpr/logo1w.png) no-repeat", + "title": "Google" + }, + "height": 110, + "html": "
    France
    ", + "nodeName": "div", + "tag": "
    France
    ", + "text": "France\n", + "visible": true, + "width": 276, + "x": 62, + "y": 76 + } + ] + +.. index:: Form + +``getFormValues()`` +------------------------------------------------------------------------------- + +**Signature:** ``getFormValues(String selector)`` + +.. versionadded:: 1.0 + +Retrieves a given form all of its field values:: + + casper.start('http://www.google.fr/', function() { + this.fill('form', {q: 'plop'}, false); + this.echo(this.getFormValues('form').q); // 'plop' + }); + + casper.run(); + +.. index:: Globals, window + +``getGlobal()`` +------------------------------------------------------------------------------- + +**Signature:** ``getGlobal(String name)`` + +Retrieves a global variable value within the remote DOM environment by its name. Basically, ``getGlobal('foo')`` will retrieve the value of ``window.foo`` from the page:: + + casper.start('http://www.google.fr/', function() { + this.echo(this.getGlobal('innerWidth')); // 1024 + }); + + casper.run(); + +.. index:: Debugging + +``getHTML()`` +------------------------------------------------------------------------------- + +**Signature:** ``getHTML([String selector, Boolean outer])`` + +.. versionadded:: 1.0 + +Retrieves HTML code from the current page. By default, it outputs the whole page HTML contents:: + + casper.start('http://www.google.fr/', function() { + this.echo(this.getHTML()); + }); + + casper.run(); + +The ``getHTML()`` method can also dump HTML contents matching a given :doc:`selector <../selectors>`; for example with this HTML code: + +.. code-block:: html + + + +

    Plop

    + + + +You can fetch those contents using:: + + casper.start('http://www.site.tld/', function() { + this.echo(this.getHTML('h1#foobar')); // => 'Plop' + }); + +The ``outer`` argument allows to retrieve the outer HTML contents of the matching element:: + + casper.start('http://www.site.tld/', function() { + this.echo(this.getHTML('h1#foobar', true)); // => '

    Plop

    ' + }); + +``getPageContent()`` +------------------------------------------------------------------------------- + +**Signature:** ``getPageContent()`` + +.. versionadded:: 1.0 + +Retrieves current page contents, dealing with exotic other content types than HTML:: + + var casper = require('casper').create(); + + casper.start().then(function() { + this.open('http://search.twitter.com/search.json?q=casperjs', { + method: 'get', + headers: { + 'Accept': 'application/json' + } + }); + }); + + casper.run(function() { + require('utils').dump(JSON.parse(this.getPageContent())); + this.exit(); + }); + +.. index:: DOM + +``getTitle()`` +------------------------------------------------------------------------------- + +**Signature:** ``getTitle()`` + +Retrieves current page title:: + + casper.start('http://www.google.fr/', function() { + this.echo(this.getTitle()); // "Google" + }); + + casper.run(); + +.. _casper_mouseevent: + +.. index:: events + +``mouseEvent()`` +------------------------------------------------------------------------------- + +**Signature:** ``mouseEvent(String type, String selector)`` + +.. versionadded:: 0.6.9 + +Triggers a mouse event on the first element found matching the provided selector. + +Supported events are ``mouseup``, ``mousedown``, ``click``, ``mousemove``, ``mouseover`` and ``mouseout``:: + + casper.start('http://www.google.fr/', function() { + this.mouseEvent('click', 'h2 a'); + }); + + casper.run(); + +.. index:: HTTP, HTTP Request, HTTP Method, HTTP Headers + +``open()`` +------------------------------------------------------------------------------- + +**Signature:** ``open(String location, Object Settings)`` + +Performs an HTTP request for opening a given location. You can forge ``GET``, ``POST``, ``PUT``, ``DELETE`` and ``HEAD`` requests. + +Example for a standard ``GET`` request:: + + casper.start(); + + casper.open('http://www.google.com/').then(function() { + this.echo('GOT it.'); + }); + + casper.run(); + +Example for a ``POST`` request:: + + casper.start(); + + casper.open('http://some.testserver.com/post.php', { + method: 'post', + data: { + 'title': 'Plop', + 'body': 'Wow.' + } + }); + + casper.then(function() { + this.echo('POSTED it.'); + }); + + casper.run(); + +To pass nested parameters arrays:: + + casper.open('http://some.testserver.com/post.php', { + method: 'post', + data: { + 'standard_param': 'foo', + 'nested_param[]': [ // please note the use of square brackets! + 'Something', + 'Something else' + ] + } + }); + +.. versionadded:: 1.0 + +You can also set custom request headers to send when performing an outgoing request, passing the ``headers`` option:: + + casper.open('http://some.testserver.com/post.php', { + method: 'post', + data: { + 'title': 'Plop', + 'body': 'Wow.' + }, + headers: { + 'Accept-Language': 'fr,fr-fr;q=0.8,en-us;q=0.5,en;q=0.3' + } + }); + +``reload()`` +------------------------------------------------------------------------------- + +**Signature:** ``reload([Function then])`` + +.. versionadded:: 1.0 + +Reloads current page location:: + + casper.start('http://google.com', function() { + this.echo("loaded"); + this.reload(function() { + this.echo("loaded again"); + }); + }); + + casper.run(); + +``repeat()`` +------------------------------------------------------------------------------- + +**Signature:** ``repeat(int times, Function then)`` + +Repeats a navigation step a given number of times:: + + casper.start().repeat(3, function() { + this.echo("Badger"); + }); + + casper.run(); + +.. _casper_resourceexists: + +.. index:: HTTP + +``resourceExists()`` +------------------------------------------------------------------------------- + +**Signature:** ``resourceExists(String|Function|RegExp test)`` + +Checks if a resource has been loaded. You can pass either a function, a string or a ``RegExp`` instance to perform the test:: + + casper.start('http://www.google.com/', function() { + if (this.resourceExists('logo3w.png')) { + this.echo('Google logo loaded'); + } else { + this.echo('Google logo not loaded', 'ERROR'); + } + }); + + casper.run(); + +.. note:: + + If you want to wait for a resource to be loaded, use the `waitForResource()`_ method. + +.. index:: Step stack, run + +``run()`` +------------------------------------------------------------------------------- + +**Signature:** ``run(fn onComplete[, int time])`` + +Runs the whole suite of steps and optionally executes a callback when they've all been done. Obviously, **calling this method is mandatory** in order to run the Casper navigation suite. + +Casper suite **won't run**:: + + casper.start('http://foo.bar/home', function() { + // ... + }); + + // hey, it's missing .run() here! + +Casper suite **will run**:: + + casper.start('http://foo.bar/home', function() { + // ... + }); + + casper.run(); + +``Casper.run()`` also accepts an ``onComplete`` callback, which you can consider as a custom final step to perform when all the other steps have been executed. Just don't forget to ``exit()`` Casper if you define one!:: + + casper.start('http://foo.bar/home', function() { + // ... + }); + + casper.then(function() { + // ... + }); + + casper.run(function() { + this.echo('So the whole suite ended.'); + this.exit(); // <--- don't forget me! + }); + +Binding a callback to ``complete.error`` will trigger when the ``onComplete`` callback fails. + +.. index:: Scroll + +``scrollTo()`` +------------------------------------------------------------------------------- + +**Signature:** ``scrollTo(Number x, Number y)`` + +.. versionadded:: 1.1-beta3 + +Scrolls current document to the coordinates defined by the value of ``x`` and ``y``:: + + casper.start('http://foo.bar/home', function() { + this.scrollTo(500, 300); + }); + +.. note:: This operation is synchronous. + +.. index:: Scroll + +``scrollToBottom()`` +------------------------------------------------------------------------------- + +**Signature:** ``scrollToBottom()`` + +.. versionadded:: 1.1-beta3 + +Scrolls current document to its bottom:: + + casper.start('http://foo.bar/home', function() { + this.scrollToBottom(); + }); + +.. note:: This operation is synchronous. + +.. index:: Form + +``sendKeys()`` +------------------------------------------------------------------------------- + +**Signature:** ``sendKeys(Selector selector, String keys[, Object options])`` + +.. versionadded:: 1.0 + +Sends native keyboard events to the element matching the provided :doc:`selector <../selectors>`:: + + casper.then(function() { + this.sendKeys('form.contact input#name', 'Duke'); + this.sendKeys('form.contact textarea#message', "Damn, I'm looking good."); + this.click('form.contact input[type="submit"]'); + }); + +.. versionadded:: 1.1 + +The currently supported HTMLElements that can receive keyboard events from ``sendKeys`` are ````, `` + + + + + + + + + + +
    + +
    + + + + diff --git a/vendor/casperjs/tests/site/frame1.html b/vendor/casperjs/tests/site/frame1.html new file mode 100755 index 0000000..0452449 --- /dev/null +++ b/vendor/casperjs/tests/site/frame1.html @@ -0,0 +1,10 @@ + + + + + CasperJS frame 1 + + +

    This is frame 1.

    + + diff --git a/vendor/casperjs/tests/site/frame2.html b/vendor/casperjs/tests/site/frame2.html new file mode 100755 index 0000000..0d34298 --- /dev/null +++ b/vendor/casperjs/tests/site/frame2.html @@ -0,0 +1,11 @@ + + + + + CasperJS frame 2 + + +

    This is frame 2.

    +

    frame 3

    + + diff --git a/vendor/casperjs/tests/site/frame3.html b/vendor/casperjs/tests/site/frame3.html new file mode 100755 index 0000000..874999c --- /dev/null +++ b/vendor/casperjs/tests/site/frame3.html @@ -0,0 +1,11 @@ + + + + + CasperJS frame 3 + + +

    This is frame 3.

    +

    frame 2

    + + diff --git a/vendor/casperjs/tests/site/frames.html b/vendor/casperjs/tests/site/frames.html new file mode 100755 index 0000000..3c75ec3 --- /dev/null +++ b/vendor/casperjs/tests/site/frames.html @@ -0,0 +1,12 @@ + + + + + CasperJS test frames + + + + + + + diff --git a/vendor/casperjs/tests/site/global.html b/vendor/casperjs/tests/site/global.html new file mode 100755 index 0000000..7a4714a --- /dev/null +++ b/vendor/casperjs/tests/site/global.html @@ -0,0 +1,14 @@ + + + + + + diff --git a/vendor/casperjs/tests/site/images/phantom.png b/vendor/casperjs/tests/site/images/phantom.png new file mode 100755 index 0000000..0a9f5ee Binary files /dev/null and b/vendor/casperjs/tests/site/images/phantom.png differ diff --git a/vendor/casperjs/tests/site/includes/include1.js b/vendor/casperjs/tests/site/includes/include1.js new file mode 100755 index 0000000..aa21f21 --- /dev/null +++ b/vendor/casperjs/tests/site/includes/include1.js @@ -0,0 +1,7 @@ +(function() { + "use strict"; + var elem = document.createElement('div'); + elem.setAttribute('id', 'include1'); + elem.appendChild(document.createTextNode('include1')); + document.querySelector('body').appendChild(elem); +})(); diff --git a/vendor/casperjs/tests/site/includes/include2.js b/vendor/casperjs/tests/site/includes/include2.js new file mode 100755 index 0000000..8bbe0bb --- /dev/null +++ b/vendor/casperjs/tests/site/includes/include2.js @@ -0,0 +1,7 @@ +(function() { + "use strict"; + var elem = document.createElement('div'); + elem.setAttribute('id', 'include2'); + elem.appendChild(document.createTextNode('include2')); + document.querySelector('body').appendChild(elem); +})(); diff --git a/vendor/casperjs/tests/site/index.html b/vendor/casperjs/tests/site/index.html new file mode 100755 index 0000000..c687926 --- /dev/null +++ b/vendor/casperjs/tests/site/index.html @@ -0,0 +1,20 @@ + + + + + CasperJS test index + + + + test + form +
      +
    • one
    • +
    • two
    • +
    • three
    • +
    + +

    Title

    + + + diff --git a/vendor/casperjs/tests/site/mouse-events.html b/vendor/casperjs/tests/site/mouse-events.html new file mode 100755 index 0000000..3336751 --- /dev/null +++ b/vendor/casperjs/tests/site/mouse-events.html @@ -0,0 +1,47 @@ + + + + + CasperJS test mouse events + + + test + test + test + test + test + test + test + test + + + diff --git a/vendor/casperjs/tests/site/multiple-forms.html b/vendor/casperjs/tests/site/multiple-forms.html new file mode 100755 index 0000000..3e9db35 --- /dev/null +++ b/vendor/casperjs/tests/site/multiple-forms.html @@ -0,0 +1,16 @@ + + + + Multiple forms test + + +
    + + +
    +
    + + +
    + + diff --git a/vendor/casperjs/tests/site/page1.html b/vendor/casperjs/tests/site/page1.html new file mode 100755 index 0000000..c3140e7 --- /dev/null +++ b/vendor/casperjs/tests/site/page1.html @@ -0,0 +1,8 @@ + + + + + CasperJS test page 1 + + Booh. + \ No newline at end of file diff --git a/vendor/casperjs/tests/site/page2.html b/vendor/casperjs/tests/site/page2.html new file mode 100755 index 0000000..3fe0f63 --- /dev/null +++ b/vendor/casperjs/tests/site/page2.html @@ -0,0 +1,8 @@ + + + + + CasperJS test page 2 + + Booh. + \ No newline at end of file diff --git a/vendor/casperjs/tests/site/page3.html b/vendor/casperjs/tests/site/page3.html new file mode 100755 index 0000000..c3140e7 --- /dev/null +++ b/vendor/casperjs/tests/site/page3.html @@ -0,0 +1,8 @@ + + + + + CasperJS test page 1 + + Booh. + \ No newline at end of file diff --git a/vendor/casperjs/tests/site/popup.html b/vendor/casperjs/tests/site/popup.html new file mode 100755 index 0000000..7f5b0c4 --- /dev/null +++ b/vendor/casperjs/tests/site/popup.html @@ -0,0 +1,18 @@ + + + + + CasperJS test popup + + + new window + close + + + diff --git a/vendor/casperjs/tests/site/prompt.html b/vendor/casperjs/tests/site/prompt.html new file mode 100755 index 0000000..291d86b --- /dev/null +++ b/vendor/casperjs/tests/site/prompt.html @@ -0,0 +1,12 @@ + + + + + CasperJS test prompt + + + + + diff --git a/vendor/casperjs/tests/site/resources.html b/vendor/casperjs/tests/site/resources.html new file mode 100755 index 0000000..6c48e43 --- /dev/null +++ b/vendor/casperjs/tests/site/resources.html @@ -0,0 +1,15 @@ + + + + + CasperJS test resource + + + + + + diff --git a/vendor/casperjs/tests/site/result.html b/vendor/casperjs/tests/site/result.html new file mode 100755 index 0000000..de43655 --- /dev/null +++ b/vendor/casperjs/tests/site/result.html @@ -0,0 +1,11 @@ + + + + + CasperJS test form result + + +

    this is the result page

    +

    Return back home

    + + \ No newline at end of file diff --git a/vendor/casperjs/tests/site/test.html b/vendor/casperjs/tests/site/test.html new file mode 100755 index 0000000..d365c97 --- /dev/null +++ b/vendor/casperjs/tests/site/test.html @@ -0,0 +1,10 @@ + + + + + CasperJS test target + + + test form + + \ No newline at end of file diff --git a/vendor/casperjs/tests/site/urls.html b/vendor/casperjs/tests/site/urls.html new file mode 100755 index 0000000..726af18 --- /dev/null +++ b/vendor/casperjs/tests/site/urls.html @@ -0,0 +1,14 @@ + + + + + CasperJS url tests + + + + + diff --git a/vendor/casperjs/tests/site/visible.html b/vendor/casperjs/tests/site/visible.html new file mode 100755 index 0000000..d05da0b --- /dev/null +++ b/vendor/casperjs/tests/site/visible.html @@ -0,0 +1,17 @@ + + + + + CasperJS test index + + + + + + + + diff --git a/vendor/casperjs/tests/site/waitFor.html b/vendor/casperjs/tests/site/waitFor.html new file mode 100755 index 0000000..a1d8994 --- /dev/null +++ b/vendor/casperjs/tests/site/waitFor.html @@ -0,0 +1,29 @@ + + + + + waitFor test + + + +
      +
    • one
    • +
    • two
    • +
    • three
    • +
    +
    + Loading... +
    +
    Voilà
    +

    I'm hidden.

    +

    I'm visible.

    + + + diff --git a/vendor/casperjs/tests/suites/.casper b/vendor/casperjs/tests/suites/.casper new file mode 100755 index 0000000..e69de29 diff --git a/vendor/casperjs/tests/suites/casper/.casper b/vendor/casperjs/tests/suites/casper/.casper new file mode 100755 index 0000000..e69de29 diff --git a/vendor/casperjs/tests/suites/casper/agent.js b/vendor/casperjs/tests/suites/casper/agent.js new file mode 100755 index 0000000..7dfd674 --- /dev/null +++ b/vendor/casperjs/tests/suites/casper/agent.js @@ -0,0 +1,32 @@ +/*global casper*/ +/*jshint strict:false*/ +function testUA(ua, match) { + casper.test.assertMatch( + ua, match, 'Default user agent matches ' + match + ); +} + +function fetchUA(requestData, request) { + var headers = requestData.headers.filter(function(header) { + return header.name === "User-Agent"; + }); + casper.test.assert(headers.length > 0); + testUA(headers.pop().value, /plop/); +} + +casper.test.begin('userAgent() tests', 3, { + originalUA: casper.options.pageSettings.userAgent, + + tearDown: function(test) { + casper.userAgent(this.originalUA); + }, + + test: function(test) { + testUA(casper.options.pageSettings.userAgent, /CasperJS/); + casper.start().userAgent('plop').once('resource.requested', fetchUA); + casper.thenOpen('tests/site/index.html').run(function() { + test.done(); + }); + } +}); + diff --git a/vendor/casperjs/tests/suites/casper/alert.js b/vendor/casperjs/tests/suites/casper/alert.js new file mode 100755 index 0000000..a0a6f85 --- /dev/null +++ b/vendor/casperjs/tests/suites/casper/alert.js @@ -0,0 +1,25 @@ +/*global casper*/ +/*jshint strict:false*/ +casper.test.begin('alert events', 1, { + ok: false, + + tearDown: function(test) { + casper.removeAllListeners('remote.alert'); + }, + + test: function(test) { + var self = this; + + casper.once('remote.alert', function(message) { + self.ok = (message === 'plop'); + }); + + casper.start('tests/site/alert.html', function() { + test.assert(self.ok, 'alert event has been intercepted'); + }); + + casper.run(function() { + test.done(); + }); + } +}); diff --git a/vendor/casperjs/tests/suites/casper/auth.js b/vendor/casperjs/tests/suites/casper/auth.js new file mode 100755 index 0000000..d575eaf --- /dev/null +++ b/vendor/casperjs/tests/suites/casper/auth.js @@ -0,0 +1,26 @@ +/*global casper*/ +/*jshint strict:false, maxstatements:99*/ + +casper.test.begin('HTTP authentication tests', 8, function(test) { + casper.start('tests/site/index.html'); + + casper.configureHttpAuth('http://localhost/'); + test.assertEquals(casper.page.settings.userName, undefined); + test.assertEquals(casper.page.settings.password, undefined); + + casper.configureHttpAuth('http://niko:plop@localhost/'); + test.assertEquals(casper.page.settings.userName, 'niko'); + test.assertEquals(casper.page.settings.password, 'plop'); + + casper.configureHttpAuth('http://localhost/', {username: 'john', password: 'doe'}); + test.assertEquals(casper.page.settings.userName, 'john'); + test.assertEquals(casper.page.settings.password, 'doe'); + + casper.configureHttpAuth('http://niko:plop@localhost/', {username: 'john', password: 'doe'}); + test.assertEquals(casper.page.settings.userName, 'niko'); + test.assertEquals(casper.page.settings.password, 'plop'); + + casper.run(function() { + test.done(); + }); +}); diff --git a/vendor/casperjs/tests/suites/casper/bypass.js b/vendor/casperjs/tests/suites/casper/bypass.js new file mode 100755 index 0000000..486d2ed --- /dev/null +++ b/vendor/casperjs/tests/suites/casper/bypass.js @@ -0,0 +1,107 @@ +/*global casper*/ +/*jshint strict:false*/ +casper.test.begin('Casper.bypass() can bypass a step', 1, function(test) { + casper.start(); + casper.then(function(){ + test.fail("This test should not be executed."); + }); + casper.bypass(1).run(function() { + test.pass("Step has been bypassed"); + test.done(); + }); +}); + +casper.test.begin('Casper.bypass() can bypass multiple steps', 1, function(test) { + casper.start(); + casper.then(function() { + test.pass("This test should be executed."); + }); + casper.then(function() { + this.bypass(2); + }); + casper.then(function() { + test.fail("This test should not be executed."); + }); + casper.then(function() { + test.fail("Nor this one."); + }); + casper.run(function() { + test.done(); + }); +}); + +casper.test.begin('Casper.thenBypass()', 1, function(test) { + casper. + thenBypass(1). + then(function() { + test.fail("This test should be bypassed."); + }). + then(function() { + test.pass("This test should be executed."); + }); + + casper.run(function() { + test.done(); + }); +}); + +casper.test.begin('Casper.thenBypassIf()', 3, function(test) { + casper. + thenBypassIf(true, 1, "Bypass if with function"). + then(function() { + test.fail("This test should be bypassed."); + }). + then(function() { + test.pass("This test should be executed."); + }). + thenBypassIf(function() { + return true; + }, 1, "Bypass if with function"). + then(function() { + test.fail("This test should be bypassed."); + }). + then(function() { + test.pass("This test should be executed."); + }). + thenBypassIf(function() { + return false; + }, 1, "Do not bypass if with function"). + then(function() { + test.pass("This test should be executed."); + }); + + casper.run(function() { + test.done(); + }); +}); + +casper.test.begin('Casper.thenBypassUnless()', 3, function(test) { + casper. + thenBypassUnless(false, 1, "Bypass unless with function"). + then(function() { + test.fail("This test should be bypassed."); + }). + then(function() { + test.pass("This test should be executed."); + }). + thenBypassUnless(function() { + return false; + }, 1, "Bypass unless with function"). + then(function() { + test.fail("This test should be bypassed."); + }). + then(function() { + test.pass("This test should be executed."); + }). + thenBypassUnless(function() { + return true; + }, 1, "Do not bypass unless with function"). + then(function() { + test.pass("This test should be executed."); + }); + + casper.run(function() { + test.done(); + }); +}); + diff --git a/vendor/casperjs/tests/suites/casper/callback.js b/vendor/casperjs/tests/suites/casper/callback.js new file mode 100755 index 0000000..e3be456 --- /dev/null +++ b/vendor/casperjs/tests/suites/casper/callback.js @@ -0,0 +1,25 @@ +/*global casper*/ +/*jshint strict:false*/ +casper.test.begin('callback events', 1, { + ok: false, + + tearDown: function(test) { + casper.removeAllListeners('remote.callback'); + }, + + test: function(test) { + var self = this; + + casper.once('remote.callback', function(data) { + self.ok = (data.hello === 'world'); + }); + + casper.start('tests/site/callback.html', function() { + test.assert(self.ok, 'callback event has been intercepted'); + }); + + casper.run(function() { + test.done(); + }); + } +}); diff --git a/vendor/casperjs/tests/suites/casper/callutils.js b/vendor/casperjs/tests/suites/casper/callutils.js new file mode 100755 index 0000000..97e1237 --- /dev/null +++ b/vendor/casperjs/tests/suites/casper/callutils.js @@ -0,0 +1,23 @@ +/*global casper*/ +/*jshint strict:false*/ +casper.test.begin('Casper.callUtils()', 2, function(test) { + casper.start("tests/site/index.html", function(){ + this.evaluate(function() { + /*global __utils__*/ + __utils__.testCallUtils = function() { + return [].slice.call(arguments); + }; + }); + + test.assertEquals(casper.callUtils("testCallUtils", "a", "b", "c"), + ["a", "b", "c"], + "Casper.callUtils() invokes a client side utility"); + + test.assertThrows(casper.callUtils, ["xxx", "a", "b", "c"], + "Casper.callUtils() raises an error if used inappropriately"); + }); + + casper.run(function() { + test.done(); + }); +}); diff --git a/vendor/casperjs/tests/suites/casper/capture.js b/vendor/casperjs/tests/suites/casper/capture.js new file mode 100755 index 0000000..b17cb8d --- /dev/null +++ b/vendor/casperjs/tests/suites/casper/capture.js @@ -0,0 +1,50 @@ +/*global casper*/ +/*jshint strict:false*/ +var fs = require('fs'); + +casper.test.begin('Casper.capture() tests', 1, { + testFile: '/tmp/__casper_test_capture.png', + + setUp: function(test) { + if (fs.exists(this.testFile) && fs.isFile(this.testFile)) { + try { + fs.remove(this.testFile); + } catch (e) { + } + } + }, + + tearDown: function(test) { + try { + fs.remove(this.testFile); + } catch(e) { + } + }, + + test: function(test) { + var self = this; + + casper.start('tests/site/index.html', function() { + this.viewport(300, 200); + this.capture(self.testFile); + test.assert(fs.isFile(self.testFile), 'Casper.capture() captured a screenshot'); + }); + + casper.run(function() { + test.done(); + }); + } +}); + +casper.test.begin('Casper.captureBase64() tests', 3, function(test) { + casper.start('tests/site/index.html', function() { + test.assert(this.captureBase64('png').length > 0, + 'Casper.captureBase64() rendered a page capture as base64'); + test.assert(this.captureBase64('png', 'ul').length > 0, + 'Casper.captureBase64() rendered a capture from a selector as base64'); + test.assert(this.captureBase64('png', {top: 0, left: 0, width: 30, height: 30}).length > 0, + 'Casper.captureBase64() rendered a capture from a clipRect as base64'); + }).run(function() { + test.done(); + }); +}); diff --git a/vendor/casperjs/tests/suites/casper/click.js b/vendor/casperjs/tests/suites/casper/click.js new file mode 100755 index 0000000..e92ca18 --- /dev/null +++ b/vendor/casperjs/tests/suites/casper/click.js @@ -0,0 +1,126 @@ +/*global casper*/ +/*jshint strict:false, maxstatements: 99*/ +var utils = require('utils'); + +casper.test.begin('click() tests', 2, function(test) { + casper.start('tests/site/index.html', function() { + this.click('a[href="test.html"]'); + }).then(function() { + test.assertTitle('CasperJS test target', 'Casper.click() can click on a link'); + }).thenClick('a', function() { + test.assertTitle('CasperJS test form', 'Casper.thenClick() can click on a link'); + }).run(function() { + test.done(); + }); +}); + +casper.test.begin('onclick variants tests', 8, function(test) { + casper.start('tests/site/click.html', function() { + test.assert(this.click('#test1'), 'Casper.click() can click an `href="javascript:` link'); + test.assert(this.click('#test2'), 'Casper.click() can click an `href="#"` link'); + test.assert(this.click('#test3'), 'Casper.click() can click an `onclick=".*; return false"` link'); + test.assert(this.click('#test4'), 'Casper.click() can click an unobstrusive js handled link'); + var results = this.getGlobal('results'); + if (phantom.casperEngine === 'slimerjs') { + // "javascript:" link in Gecko are executed asynchronously, so we don't have result at this time + test.skip(1) + } + else + test.assert(results.test1, 'Casper.click() has clicked an `href="javascript:` link'); + test.assert(results.test2, 'Casper.click() has clicked an `href="#"` link'); + test.assert(results.test3, 'Casper.click() has clicked an `onclick=".*; return false"` link'); + test.assert(results.test4, 'Casper.click() has clicked an unobstrusive js handled link'); + }).run(function() { + test.done(); + }); +}); + +casper.test.begin('clickLabel tests tests', 12, function(test) { + casper.start('tests/site/click.html', function() { + test.assert(this.clickLabel('test1'), + 'Casper.clickLabel() can click an `href="javascript:` link'); + test.assert(this.clickLabel('test2'), + 'Casper.clickLabel() can click an `href="#"` link'); + test.assert(this.clickLabel('test3'), + 'Casper.clickLabel() can click an `onclick=".*; return false"` link'); + test.assert(this.clickLabel('test4'), + 'Casper.clickLabel() can click an unobstrusive js handled link'); + test.assert(this.clickLabel('Label with double "quotes"'), + 'Casper.clickLabel() can click the link with double quotes in the label'); + test.assert(this.clickLabel("Label with single 'quotes'"), + 'Casper.clickLabel() can click the link with the single quotes in the label'); + var results = this.getGlobal('results'); + if (phantom.casperEngine === 'slimerjs') { + // "javascript:" link in Gecko are executed asynchronously, so we don't have result at this time + test.skip(1) + } + else + test.assert(results.test1, + 'Casper.clickLabel() has clicked an `href="javascript:` link'); + test.assert(results.test2, + 'Casper.clickLabel() has clicked an `href="#"` link'); + test.assert(results.test3, + 'Casper.clickLabel() has clicked an `onclick=".*; return false"` link'); + test.assert(results.test4, + 'Casper.clickLabel() has clicked an unobstrusive js handled link'); + test.assert(results.test6, + 'Casper.clickLabel() has clicked the link with double quotes in the label'); + test.assert(results.test7, + 'Casper.clickLabel() has clicked the link with single quotes in the label'); + }).run(function() { + test.done(); + }); +}); + +casper.test.begin('casper.mouse tests', 4, function(test) { + casper.start('tests/site/click.html', function() { + this.mouse.down(200, 100); + var results = this.getGlobal('results'); + test.assertEquals(results.testdown, [200, 100], + 'Mouse.down() has pressed button to the specified position'); + this.mouse.up(200, 100); + results = this.getGlobal('results'); + test.assertEquals(results.testup, [200, 100], + 'Mouse.up() has released button to the specified position'); + this.mouse.move(200, 100); + results = this.getGlobal('results'); + test.assertEquals(results.testmove, [200, 100], + 'Mouse.move() has moved to the specified position'); + if (utils.gteVersion(phantom.version, '1.8.0')) { + this.mouse.doubleclick(200, 100); + results = this.getGlobal('results'); + this.test.assertEquals(results.testdoubleclick, [200, 100], + 'Mouse.doubleclick() double-clicked the specified position'); + } else { + this.test.pass("Mouse.doubleclick() requires PhantomJS >= 1.8"); + } + }).run(function() { + test.done(); + }); +}); + +casper.test.begin('element focus on click', 1, function(test) { + casper.start().then(function() { + this.page.content = '
    ' + this.click('form input[name=foo]') + this.page.sendEvent('keypress', 'bar'); + test.assertEquals(this.getFormValues('form')['foo'], 'bar', + 'Casper.click() sets the focus on clicked element'); + }).run(function() { + test.done(); + }); +}); + +casper.test.begin('mouse events on click', 2, function(test) { + casper.start('tests/site/click.html', function() { + this.click('#test5'); + }).then(function() { + var results = this.getGlobal('results'); + test.assert(results.test5.indexOf('mousedown') !== -1, + 'Casper.click() triggers mousedown event'); + test.assert(results.test5.indexOf('mouseup') !== -1, + 'Casper.click() triggers mouseup event'); + }).run(function() { + test.done(); + }); +}); diff --git a/vendor/casperjs/tests/suites/casper/confirm.js b/vendor/casperjs/tests/suites/casper/confirm.js new file mode 100755 index 0000000..fac3933 --- /dev/null +++ b/vendor/casperjs/tests/suites/casper/confirm.js @@ -0,0 +1,53 @@ +/*global casper*/ +/*jshint strict:false*/ +casper.test.begin('can confirm dialog', 2, { + received: undefined, + + setUp: function(test) { + var self = this; + casper.removeAllFilters('page.confirm'); + casper.setFilter('page.confirm', function(message) { + self.received = message; + return true; + }); + }, + + tearDown: function(test) { + casper.removeAllFilters('page.confirm'); + }, + + test: function(test) { + var self = this; + casper.start('tests/site/confirm.html', function() { + test.assert(this.getGlobal('confirmed'), 'confirmation dialog accepted'); + }).run(function() { + test.assertEquals(self.received, 'are you sure?', 'confirmation message is ok'); + test.done(); + }); + } +}); + +casper.test.begin('can cancel dialog', { + received: undefined, + + setUp: function(test) { + var self = this; + casper.removeAllFilters('page.confirm'); + casper.setFilter('page.confirm', function(message) { + return false; + }); + }, + + tearDown: function(test) { + casper.removeAllFilters('page.confirm'); + }, + + test: function(test) { + var self = this; + casper.start('tests/site/confirm.html', function() { + test.assertNot(this.getGlobal('confirmed'), 'confirmation dialog canceled'); + }).run(function() { + test.done(); + }); + } +}); diff --git a/vendor/casperjs/tests/suites/casper/content.js b/vendor/casperjs/tests/suites/casper/content.js new file mode 100755 index 0000000..72fde2c --- /dev/null +++ b/vendor/casperjs/tests/suites/casper/content.js @@ -0,0 +1,21 @@ +/*global casper*/ +/*jshint strict:false*/ +var fs = require("fs"); + +casper.test.begin("Casper.getPageContent() text/html content", 1, function(test) { + casper.start("tests/site/test.html", function() { + test.assertMatch(this.getPageContent(), /CasperJS test target/, + "Casper.getPageContent() retrieves text/html content"); + }).run(function() { + test.done(); + }); +}); + +casper.test.begin("Casper.getPageContent() non text/html content", 1, function(test) { + casper.start("tests/site/dummy.js", function() { + test.assertEquals(this.getPageContent(), "document.write('foo');", + "Casper.getPageContent() retrieves non text/html content"); + }).run(function() { + test.done(); + }); +}); diff --git a/vendor/casperjs/tests/suites/casper/debug.js b/vendor/casperjs/tests/suites/casper/debug.js new file mode 100755 index 0000000..6095c28 --- /dev/null +++ b/vendor/casperjs/tests/suites/casper/debug.js @@ -0,0 +1,12 @@ +/*global casper*/ +/*jshint strict:false*/ +casper.test.begin('getHTML() tests', 2, function(test) { + casper.start('tests/site/index.html', function() { + test.assertEquals(this.getHTML('ul li'), 'one', + 'Casper.getHTML() retrieves inner HTML by default'); + test.assertEquals(this.getHTML('ul li', true), '<li>one</li>', + 'Casper.getHTML() can retrieve outer HTML'); + }).run(function() { + test.done(); + }); +}); diff --git a/vendor/casperjs/tests/suites/casper/elementattribute.js b/vendor/casperjs/tests/suites/casper/elementattribute.js new file mode 100755 index 0000000..4a0885a --- /dev/null +++ b/vendor/casperjs/tests/suites/casper/elementattribute.js @@ -0,0 +1,21 @@ +/*global casper*/ +/*jshint strict:false*/ +var x = require('casper').selectXPath; + +casper.test.begin('getElementAttribute() tests', 4, function(test) { + casper.start('tests/site/elementattribute.html', function() { + test.assertEquals(this.getElementAttribute('.testo', 'data-stuff'), + 'beautiful string', 'Casper.getElementAttribute() works with a CSS selector'); + test.assertEquals(this.getElementAttribute(x('//div[@class]'), 'data-stuff'), + 'beautiful string', 'Casper.getElementAttribute() works with a XPath selector'); + }).then(function() { + test.assertEquals(this.getElementsAttribute('.testo', 'data-stuff'), + ['beautiful string', 'not as beautiful string'], + 'Casper.getElementsAttribute() works with a CSS selector'); + test.assertEquals(this.getElementsAttribute(x('//div[@class]'), 'data-stuff'), + ['beautiful string', 'not as beautiful string'], + 'Casper.getElementsAttribute() works with a XPath selector'); + }).run(function() { + test.done(); + }); +}); diff --git a/vendor/casperjs/tests/suites/casper/encode.js b/vendor/casperjs/tests/suites/casper/encode.js new file mode 100755 index 0000000..9c85d14 --- /dev/null +++ b/vendor/casperjs/tests/suites/casper/encode.js @@ -0,0 +1,19 @@ +/*global casper*/ +/*jshint strict:false*/ +var fs = require('fs'); + +casper.test.begin('base64encode() and download() tests', 2, function(test) { + // FIXME: https://github.com/ariya/phantomjs/pull/364 has been merged, update scheme + casper.start('file://' + phantom.casperPath + '/tests/site/index.html', function() { + var imageUrl = 'file://' + phantom.casperPath + '/tests/site/images/phantom.png', + image = this.base64encode(imageUrl); + test.assertEquals(image.length, 6160, 'Casper.base64encode() can retrieve base64 contents'); + this.download(imageUrl, '__test_logo.png'); + test.assert(fs.exists('__test_logo.png'), 'Casper.download() downloads a file'); + if (fs.exists('__test_logo.png')) { + fs.remove('__test_logo.png'); + } + }).run(function() { + test.done(); + }); +}); diff --git a/vendor/casperjs/tests/suites/casper/evaluate.js b/vendor/casperjs/tests/suites/casper/evaluate.js new file mode 100755 index 0000000..43f58bd --- /dev/null +++ b/vendor/casperjs/tests/suites/casper/evaluate.js @@ -0,0 +1,112 @@ +/*global casper*/ +/*jshint strict:false, maxparams:99*/ +casper.test.begin('mapping argument context', 1, function(test) { + casper.start(); + var context = { + "_boolean_true": true, + "_boolean_false": false, + "_int_number": 42, + "_float_number": 1337.42, + "_string": "plop! \"Ÿ£$\" 'no'", + "_array": [1, 2, 3], + "_object": {a: 1, b: 2}, + "_function": function(){console.log('ok');} + }; + var result = casper.evaluate(function(_boolean_true, _boolean_false, _int_number, + _float_number, _string, _array, _object, _function) { + return [].map.call(arguments, function(arg) { + return typeof(arg); + }); + }, context); + test.assertEquals( + result.toString(), + ['boolean', 'boolean', 'number', 'number', 'string', 'object', 'object', 'function'].toString(), + 'Casper.evaluate() handles passed argument context correcly' + ); + test.done(); +}); + +casper.test.begin('handling no argument context', 1, function(test) { + casper.start(); + test.assertEquals(casper.evaluate(function() { + return 42; + }), 42, 'Casper.evaluate() handles evaluation with no context passed'); + test.done(); +}); + +casper.test.begin('handling of object context (BC mode)', 3, function(test) { + casper.start(); + test.assertEquals(casper.evaluate(function(a) { + return [a]; + }, {a: "foo"}), ["foo"], 'Casper.evaluate() accepts an object as arguments context'); + test.assertEquals(casper.evaluate(function(a, b) { + return [a, b]; + }, {a: "foo", b: "bar"}), ["foo", "bar"], 'Casper.evaluate() accepts an object as arguments context'); + test.assertEquals(casper.evaluate(function(a, b, c) { + return [a, b, c]; + }, {a: "foo", b: "bar", c: "baz"}), ["foo", "bar", "baz"], 'Casper.evaluate() accepts an object as arguments context'); + test.done(); +}); + +casper.test.begin('handling of array context', 3, function(test) { + casper.start(); + test.assertEquals(casper.evaluate(function(a) { + return [a]; + }, ["foo"]), ["foo"], 'Casper.evaluate() accepts an array as arguments context'); + test.assertEquals(casper.evaluate(function(a, b) { + return [a, b]; + }, ["foo", "bar"]), ["foo", "bar"], 'Casper.evaluate() accepts an array as arguments context'); + test.assertEquals(casper.evaluate(function(a, b, c) { + return [a, b, c]; + }, ["foo", "bar", "baz"]), ["foo", "bar", "baz"], 'Casper.evaluate() accepts an array as arguments context'); + test.done(); +}); + +casper.test.begin('natural arguments context (phantomjs equivalent)', 3, function(test) { + casper.start(); + test.assertEquals(casper.evaluate(function(a) { + return [a]; + }, "foo"), ["foo"], 'Casper.evaluate() accepts natural arguments context'); + test.assertEquals(casper.evaluate(function(a, b) { + return [a, b]; + }, "foo", "bar"), ["foo", "bar"], 'Casper.evaluate() accepts natural arguments context'); + test.assertEquals(casper.evaluate(function(a, b, c) { + return [a, b, c]; + }, "foo", "bar", "baz"), ["foo", "bar", "baz"], 'Casper.evaluate() accepts natural arguments context'); + test.done(); +}); + +casper.test.begin('thenEvaluate() tests', 2, function(test) { + casper.start().thenEvaluate(function(a, b) { + window.a = a + window.b = b; + }, "foo", "bar"); + casper.then(function() { + test.assertEquals(this.getGlobal('a'), "foo", "Casper.thenEvaluate() sets args"); + test.assertEquals(this.getGlobal('b'), "bar", + "Casper.thenEvaluate() sets args the same way evaluate() does"); + }); + casper.run(function() { + test.done(); + }); +}); + +// https://github.com/n1k0/casperjs/issues/489 +// https://groups.google.com/forum/?fromgroups=#!topic/casperjs/95IgDMFnEKM +casper.test.begin("evaluate() returns a value which can be altered", 1, function(test) { + var list; + + casper.start().then(function() { + list = this.evaluate(function() { + return [{a: 1}, {b: 2}]; + }); + var first = list[0]; + first.a = 42; + test.assertEquals(list, [{a: 42}, {b: 2}], + 'evaluate() returns a cloned value which can be altered'); + }); + + casper.run(function() { + test.done(); + }); +}); diff --git a/vendor/casperjs/tests/suites/casper/events.js b/vendor/casperjs/tests/suites/casper/events.js new file mode 100755 index 0000000..2a08b12 --- /dev/null +++ b/vendor/casperjs/tests/suites/casper/events.js @@ -0,0 +1,29 @@ +/*global casper*/ +/*jshint strict:false*/ +casper.test.begin('events', 2, function(test) { + casper.plopped = false; + casper.once("plop", function() { + this.plopped = true; + }); + test.assert(Object.keys(casper._events).some(function(i) { + return i === "plop"; + }), "on() has set an event handler"); + casper.emit("plop"); + test.assert(casper.plopped, "emit() emits an event"); + test.done(); +}); + +casper.test.begin('filters', 3, function(test) { + casper.foo = 0; + casper.setFilter("test", function(a) { + this.foo = 42; + return a + 1; + }); + test.assert(Object.keys(casper._filters).some(function(i) { + return i === "test"; + }), "setFilter() has set a filter"); + test.assertEquals(casper.filter("test", 1), 2, "filter() filters a value"); + test.assertEquals(casper.foo, 42, "filter() applies the correct context"); + delete casper.foo; + test.done(); +}); diff --git a/vendor/casperjs/tests/suites/casper/exists.js b/vendor/casperjs/tests/suites/casper/exists.js new file mode 100755 index 0000000..f60e617 --- /dev/null +++ b/vendor/casperjs/tests/suites/casper/exists.js @@ -0,0 +1,10 @@ +/*global casper*/ +/*jshint strict:false*/ +casper.test.begin('exists() tests', 2, function(test) { + casper.start('tests/site/index.html', function() { + test.assert(this.exists('a'), 'Casper.exists() can check if an element exists'); + test.assertNot(this.exists('chucknorriz'), 'Casper.exists() can check than an element does not exist') + }).run(function() { + test.done(); + }); +}); diff --git a/vendor/casperjs/tests/suites/casper/fetchtext.js b/vendor/casperjs/tests/suites/casper/fetchtext.js new file mode 100755 index 0000000..57bbbf7 --- /dev/null +++ b/vendor/casperjs/tests/suites/casper/fetchtext.js @@ -0,0 +1,21 @@ +/*global casper*/ +/*jshint strict:false*/ +casper.test.begin('fetchText() basic tests', 1, function(test) { + casper.start('tests/site/index.html', function() { + test.assertEquals(this.fetchText('ul li'), 'onetwothree', + 'Casper.fetchText() can retrieve text contents'); + }).run(function() { + test.done(); + }); +}); + +casper.test.begin('fetchText() handles HTML entities', 1, function(test) { + casper.start().then(function() { + this.setContent('<html><body>Voilà</body></html>'); + test.assertEquals(this.fetchText('body'), 'Voilà', + 'Casper.fetchText() fetches decoded text'); + }); + casper.run(function() { + test.done(); + }); +}); diff --git a/vendor/casperjs/tests/suites/casper/flow.coffee b/vendor/casperjs/tests/suites/casper/flow.coffee new file mode 100755 index 0000000..01473fb --- /dev/null +++ b/vendor/casperjs/tests/suites/casper/flow.coffee @@ -0,0 +1,38 @@ +casper.test.begin 'handling waits and timeouts', 13, (test) -> + step = 0 + + casper.start "tests/site/resources.html", -> + test.assertEquals ++step, 1, "step 1" + @wait 400, -> + test.assertEquals ++step, 2, "step 1.1" + @wait 200, -> + test.assertEquals ++step, 3, "step 1.1.1" + @wait 200, -> + test.assertEquals ++step, 4, "step 1.1.1.1" + @then -> + test.assertEquals ++step, 5, "step 1.1.2.1" + @wait 400, -> + test.assertEquals ++step, 6, "step 1.2" + + casper.wait 200, -> + test.assertEquals ++step, 7, "step 2" + + casper.waitForSelector( + '#noneExistingSelector' + -> test.fail "should run into timeout" + -> test.assertEquals ++step, 8, "step 3 sucessfully timed out" + 1000 + ) + casper.then -> + test.assertEquals ++step, 9, "step 4" + @wait 300, -> + test.assertEquals ++step, 10, "step 4.1" + @wait 300, -> + test.assertEquals ++step, 11, "step 4.1.1" + @wait 100, -> + test.assertEquals ++step, 12, "step 5.2" + + casper.then -> + test.assertEquals ++step, 13, "last step" + + casper.run(-> test.done()) diff --git a/vendor/casperjs/tests/suites/casper/formfill.js b/vendor/casperjs/tests/suites/casper/formfill.js new file mode 100755 index 0000000..08d22c8 --- /dev/null +++ b/vendor/casperjs/tests/suites/casper/formfill.js @@ -0,0 +1,231 @@ +/*global casper, __utils__*/ +/*jshint strict:false*/ +var fs = require('fs'); + +function testFormValues(test) { + test.assertField('email', 'chuck@norris.com', + 'can fill an input[type=text] form field'); + test.assertField('password', 'chuck', + 'can fill an input[type=password] form field') + test.assertField('content', 'Am watching thou', + 'can fill a textarea form field'); + test.assertField('topic', 'bar', + 'can pick a value from a select form field'); + test.assertField('check', true, + 'can check a form checkbox'); + test.assertEvalEquals(function() { + return __utils__.findOne('input[name="choice"][value="no"]').checked; + }, true, 'can check a form radio button 1/2'); + test.assertEvalEquals(function() { + return __utils__.findOne('input[name="choice"][value="yes"]').checked; + }, false, 'can check a form radio button 2/2'); + test.assertEvalEquals(function() { + return (__utils__.findOne('input[name="checklist[]"][value="1"]').checked && + !__utils__.findOne('input[name="checklist[]"][value="2"]').checked && + __utils__.findOne('input[name="checklist[]"][value="3"]').checked); + }, true, 'can fill a list of checkboxes'); +} + +function testUrl(test) { + test.assertUrlMatch(/email=chuck@norris.com/, 'input[type=email] field was submitted'); + test.assertUrlMatch(/password=chuck/, 'input[type=password] field was submitted'); + test.assertUrlMatch(/content=Am\+watching\+thou/, 'textarea field was submitted'); + test.assertUrlMatch(/check=on/, 'input[type=checkbox] field was submitted'); + test.assertUrlMatch(/choice=no/, 'input[type=radio] field was submitted'); + test.assertUrlMatch(/topic=bar/, 'select field was submitted'); + test.assertUrlMatch(/strange=very/, 'strangely typed input field was submitted'); +} + +casper.test.begin('fill() & fillNames() tests', 16, function(test) { + var fpath = fs.pathJoin(phantom.casperPath, 'README.md'); + + casper.start('tests/site/form.html', function() { + this.fill('form[action="result.html"]', { + email: 'chuck@norris.com', + password: 'chuck', + content: 'Am watching thou', + check: true, + choice: 'no', + topic: 'bar', + file: fpath, + 'checklist[]': ['1', '3'], + strange: "very" + }); + testFormValues(test); + test.assertEvalEquals(function() { + return __utils__.findOne('input[name="file"]').files.length === 1; + }, true, 'can select a file to upload'); + }); + casper.thenClick('input[type="submit"]', function() { + testUrl(test); + }); + casper.run(function() { + test.done(); + }); +}); + +casper.test.begin('fillSelectors() tests', 16, function(test) { + var fpath = fs.pathJoin(phantom.casperPath, 'README.md'); + + casper.start('tests/site/form.html', function() { + this.fillSelectors('form[action="result.html"]', { + "input[name='email']": 'chuck@norris.com', + "input[name='password']": 'chuck', + "textarea[name='content']": 'Am watching thou', + "input[name='check']": true, + "input[name='choice']": 'no', + "select[name='topic']": 'bar', + "input[name='file']": fpath, + "input[name='checklist[]']": ['1', '3'], + "input[name='strange']": "very" + }); + testFormValues(test); + test.assertEvalEquals(function() { + return __utils__.findOne('input[name="file"]').files.length === 1; + }, true, 'can select a file to upload'); + }); + casper.thenClick('input[type="submit"]', function() { + testUrl(test); + }); + casper.run(function() { + test.done(); + }); +}); + +casper.test.begin('fillXPath() tests', 15, function(test) { + casper.start('tests/site/form.html', function() { + this.fillXPath('form[action="result.html"]', { + '//input[@name="email"]': 'chuck@norris.com', + '//input[@name="password"]': 'chuck', + '//textarea[@name="content"]': 'Am watching thou', + '//input[@name="check"]': true, + '//input[@name="choice"]': 'no', + '//select[@name="topic"]': 'bar', + '//input[@name="checklist[]"]': ['1', '3'], + '//input[@name="strange"]': "very" + }); + testFormValues(test); + // note: file inputs cannot be filled using XPath + }); + casper.thenClick('input[type="submit"]', function() { + testUrl(test); + }); + casper.run(function() { + test.done(); + }); +}); + +casper.test.begin('nonexistent fields', 1, function(test) { + casper.start('tests/site/form.html', function() { + test.assertRaises(this.fill, ['form[action="result.html"]', { + nonexistent: 42 + }, true], 'Casper.fill() raises an exception when unable to fill a form'); + }).run(function() { + test.done(); + }); +}); + +casper.test.begin('multiple forms', 2, function(test) { + casper.start('tests/site/multiple-forms.html', function() { + this.fill('form[name="f2"]', { + yo: "ok" + }, true); + }).then(function() { + test.assertUrlMatch(/\?f=f2&yo=ok$/, 'Casper.fill() handles multiple forms'); + }).then(function() { + this.fill('form[name="f2"]', { + yo: "ok" + }); + test.assertEquals(this.getFormValues('form[name="f2"]'), { + f: "f2", + yo: "ok" + }, 'Casper.getFormValues() retrieves filled values when multiple forms have same field names'); + }).run(function() { + test.done(); + }); +}); + +casper.test.begin('field array', 1, function(test) { + // issue #267: array syntax field names + casper.start('tests/site/field-array.html', function() { + this.fill('form', { + 'foo[bar]': "bar", + 'foo[baz]': "baz" + }, true); + }).then(function() { + test.assertUrlMatch('?foo[bar]=bar&foo[baz]=baz', + 'Casper.fill() handles array syntax field names'); + }).run(function() { + test.done(); + }); +}); + +casper.test.begin('getFormValues() tests', 2, function(test) { + var fpath = fs.pathJoin(phantom.casperPath, 'README.md'); + var fileValue = 'README.md'; + if (phantom.casperEngine === 'phantomjs') { + fileValue = 'C:\\fakepath\\README.md'; // phantomjs/webkit sets that; + } + + casper.start('tests/site/form.html', function() { + this.fill('form[action="result.html"]', { + email: 'chuck@norris.com', + password: 'chuck', + language: 'english', + content: 'Am watching thou', + check: true, + choice: 'no', + topic: 'bar', + file: fpath, + 'checklist[]': ['1', '3'], + strange: "very" + }); + }); + casper.then(function() { + test.assertEquals(this.getFormValues('form'), { + "check": true, + "checklist[]": ["1", "3"], + "choice": "no", + "content": "Am watching thou", + "email": "chuck@norris.com", + "file": fileValue, + "password": "chuck", + "submit": "submit", + "language": "english", + "topic": "bar", + "strange": "very" + }, 'Casper.getFormValues() retrieves filled values'); + }); + casper.then(function() { + this.fill('form[action="result.html"]', { + email: 'chuck@norris.com', + password: 'chuck', + language: 'english', + content: 'Am watching thou', + check: true, + choice: 'yes', + topic: 'bar', + file: fpath, + 'checklist[]': ['1', '3'], + strange: "very" + }); + }); + casper.then(function() { + test.assertEquals(this.getFormValues('form'), { + "check": true, + "checklist[]": ["1", "3"], + "choice": "yes", + "content": "Am watching thou", + "email": "chuck@norris.com", + "file": fileValue, + "password": "chuck", + "language": "english", + "submit": "submit", + "topic": "bar", + "strange": "very" + }, 'Casper.getFormValues() correctly retrieves values from radio inputs regardless of order'); + }); + casper.run(function() { + test.done(); + }); +}); diff --git a/vendor/casperjs/tests/suites/casper/frames.js b/vendor/casperjs/tests/suites/casper/frames.js new file mode 100755 index 0000000..785be97 --- /dev/null +++ b/vendor/casperjs/tests/suites/casper/frames.js @@ -0,0 +1,45 @@ +/*global casper, __utils__*/ +/*jshint strict:false*/ +casper.test.begin('handling frames', 16, function(test) { + casper.start('tests/site/frames.html'); + + casper.withFrame('frame1', function() { + test.assertTitle('CasperJS frame 1'); + test.assertExists("#f1"); + test.assertDoesntExist("#f2"); + test.assertEval(function() { + return '__utils__' in window && 'getBinary' in __utils__; + }, '__utils__ object is available in child frame'); + test.assertMatches(this.page.frameContent, /This is frame 1/); + test.assertMatches(this.getHTML(), /This is frame 1/); + }); + + casper.withFrame('frame2', function() { + test.assertTitle('CasperJS frame 2'); + test.assertExists("#f2"); + test.assertDoesntExist("#f1"); + test.assertEval(function() { + return '__utils__' in window && 'getBinary' in __utils__; + }, '__utils__ object is available in other child frame'); + this.clickLabel('frame 3'); + }); + + casper.withFrame('frame2', function() { + test.assertTitle('CasperJS frame 3'); + }); + + casper.withFrame(0, function() { + test.assertTitle('CasperJS frame 1'); + test.assertExists("#f1"); + test.assertDoesntExist("#f2"); + }); + + casper.withFrame(1, function() { + test.assertTitle('CasperJS frame 3'); + }); + + casper.run(function() { + test.assertTitle('CasperJS test frames'); + test.done(); + }); +}); diff --git a/vendor/casperjs/tests/suites/casper/global.js b/vendor/casperjs/tests/suites/casper/global.js new file mode 100755 index 0000000..9e818e0 --- /dev/null +++ b/vendor/casperjs/tests/suites/casper/global.js @@ -0,0 +1,14 @@ +/*global casper*/ +/*jshint strict:false*/ +casper.test.begin('getGLobal() tests', 3, function(test) { + casper.start('tests/site/global.html', function() { + test.assertEquals(this.getGlobal('myGlobal'), 'awesome string', + 'Casper.getGlobal() can retrieve a remote global variable'); + test.assertEquals(this.getGlobal('myObject').foo.bar, 'baz', + 'Casper.getGlobal() can retrieves a serializable object'); + test.assertRaises(this.getGlobal, ['myUnencodableGlobal'], + 'Casper.getGlobal() does not fail trying to encode an unserializable global'); + }).run(function() { + test.done(); + }); +}); diff --git a/vendor/casperjs/tests/suites/casper/headers.js b/vendor/casperjs/tests/suites/casper/headers.js new file mode 100755 index 0000000..8e5bbb4 --- /dev/null +++ b/vendor/casperjs/tests/suites/casper/headers.js @@ -0,0 +1,33 @@ +/*global casper*/ +/*jshint strict:false*/ +var server = require('webserver').create(); +var service = server.listen(8090, function(request, response) { + response.statusCode = 200; + response.headers = { + 'Content-Language': 'en', + 'Content-Type': 'text/html', + 'Date': new Date().toUTCString() + }; + response.write("ok"); + response.close(); +}); + +casper.test.begin('Casper.headers.get() using file protocol', 1, function(test) { + casper.start('file://' + phantom.casperPath + 'tests/site/index.html', function(response) { + test.assertEquals(response, {data: null}, 'Empty http response on local page'); + }).run(function() { + test.done(); + }) +}); + +casper.test.begin('Casper.headers.get() using http protocol', 3, function(test) { + casper.start('http://localhost:8090/', function(response) { + var headers = response.headers; + test.assertEquals(headers.get('Content-Language'), 'en', 'Checking existing header (case sensitive)'); + test.assertEquals(headers.get('content-language'), 'en', 'Checking existing header (case insensitive)'); + test.assertEquals(headers.get('X-Is-Troll'), null, 'Checking unexisting header'); + }).run(function() { + server.close(); + test.done(); + }) +}); diff --git a/vendor/casperjs/tests/suites/casper/history.js b/vendor/casperjs/tests/suites/casper/history.js new file mode 100755 index 0000000..5c6b483 --- /dev/null +++ b/vendor/casperjs/tests/suites/casper/history.js @@ -0,0 +1,23 @@ +/*global casper*/ +/*jshint strict:false*/ +casper.test.begin('handling navigation history', 4, function(test) { + casper.start('tests/site/page1.html'); + casper.thenOpen('tests/site/page2.html'); + casper.thenOpen('tests/site/page3.html'); + casper.back(); + casper.then(function() { + test.assertMatch(this.getCurrentUrl(), /page2\.html$/, + 'Casper.back() can go back an history step'); + }); + casper.forward(); + casper.then(function() { + test.assertMatch(this.getCurrentUrl(), /page3\.html$/, + 'Casper.forward() can go forward an history step'); + }); + casper.run(function() { + test.assert(this.history.length > 0, 'Casper.history contains urls'); + test.assertMatch(this.history[0], /page1\.html$/, + 'Casper.history has the correct first url'); + test.done(); + }); +}); diff --git a/vendor/casperjs/tests/suites/casper/hooks.js b/vendor/casperjs/tests/suites/casper/hooks.js new file mode 100755 index 0000000..cc6a44b --- /dev/null +++ b/vendor/casperjs/tests/suites/casper/hooks.js @@ -0,0 +1,65 @@ +/*global casper*/ +/*jshint strict:false*/ +casper.test.begin('onStepComplete() hook tests', 1, function(test) { + var stepResults = []; + casper.options.onStepComplete = function(self, stepResult) { + stepResults.push(stepResult); + }; + casper.start('tests/site/index.html', function() { + return 'ok'; + }); + casper.run(function() { + test.assert(stepResults.indexOf('ok') > -1, + 'Casper.options.onStepComplete() is called on step complete'); + this.options.onStepComplete = undefined; + test.done(); + }); +}); + +casper.test.begin('onResourceRequested() & onResourceReceived() hook tests', 6, function(test) { + var requests = [], responses = []; + casper.options.onResourceRequested = function(self, request) { + requests.push(request); + }; + casper.options.onResourceReceived = function(self, response) { + responses.push(response); + }; + casper.start('tests/site/index.html', function() { + test.assert(requests.some(function(request) { + return (/index\.html$/).test(request.url); + }), 'onResourceRequested() receives page requests'); + test.assert(requests.some(function(request) { + return (/phantom\.png$/).test(request.url); + }), 'onResourceRequested() receives image requests'); + test.assert(responses.some(function(response) { + return response.stage === 'start' && (/index\.html$/).test(response.url); + }), 'onResourceReceived() receives page response on load start'); + test.assert(responses.some(function(response) { + return response.stage === 'end' && (/index\.html$/).test(response.url); + }), 'onResourceReceived() receives page response on load end'); + test.assert(responses.some(function(response) { + return response.stage === 'start' && (/phantom\.png$/).test(response.url); + }), 'onResourceReceived() receives image response on load start'); + test.assert(responses.some(function(response) { + return response.stage === 'end' && (/phantom\.png$/).test(response.url); + }), 'onResourceReceived() receives image response on load end'); + }); + casper.run(function() { + this.options.onResourceReceived = this.options.onResourceRequested = undefined; + test.done(); + }); +}); + +casper.test.begin('onAlert() hook tests', 1, function(test) { + var message; + casper.options.onAlert = function(self, msg) { + message = msg; + }; + casper.start('tests/site/alert.html', function() { + test.assertEquals(message, 'plop', 'Casper.options.onAlert() can intercept an alert message'); + }); + casper.run(function() { + this.options.onAlert = null; + test.done(); + }); +}); diff --git a/vendor/casperjs/tests/suites/casper/keys.js b/vendor/casperjs/tests/suites/casper/keys.js new file mode 100755 index 0000000..1c292b7 --- /dev/null +++ b/vendor/casperjs/tests/suites/casper/keys.js @@ -0,0 +1,72 @@ +/*jshint strict:false*/ +/*global CasperError, casper, console, phantom, require*/ +var utils = require('utils'); + +casper.test.begin('sendKeys() tests', 4, function(test) { + casper.start('tests/site/form.html', function() { + this.sendKeys('input[name="email"]', 'duke@nuk.em'); + this.sendKeys('input[name="language"]', 'fr', {keepFocus: true}); + this.click('#autocomplete li:first-child'); + this.sendKeys('textarea', "Damn, I’m looking good."); + var values = this.getFormValues('form[action="result.html"]'); + test.assertEquals(values.email, 'duke@nuk.em', + 'Casper.sendKeys() sends keys to given input'); + test.assertEquals(values.language, 'french', + 'Casper.sendKeys() sends keys to given input and keeps focus afterweards'); + test.assertEquals(values.content, "Damn, I’m looking good.", + 'Casper.sendKeys() sends keys to given textarea'); + + this.sendKeys('input[name="notype"]', "I have no type."); + values = this.getFormValues('form#no-type-test-form'); + test.assertEquals(values.notype, "I have no type.", + 'Casper.sendKeys() sends keys to given input without type attribute'); + }).run(function() { + test.done(); + }); +}); + +casper.test.begin('sendKeys() works on content-editable elements', function(test) { + casper.start('tests/site/elementattribute.html', function() { + this.click('#content-editable-div'); + this.sendKeys('#content-editable-div', 'A Clockwork Orange'); + }).then(function() { + test.assertSelectorHasText('#content-editable-div','A Clockwork Orange'); + }).run(function() { + test.done(); + }); +}); + +if (utils.gteVersion(phantom.version, '1.9.0')) { + casper.test.begin('sendKeys() key modifiers tests', 1, function(test) { + casper.start().then(function() { + this.setContent([ + '<input>', + '<script>var keys = []; window.addEventListener("keypress", function(e) {', + ' keys.push({code: e.which, alt: e.altKey, ctrl: e.ctrlKey});', + '})</script>' + ].join('')); + this.sendKeys('input', 'k'); + this.sendKeys('input', 'k', {modifiers: "ctrl"}); + this.sendKeys('input', 'k', {modifiers: "ctrl+alt"}); + test.assertEquals(this.getGlobal('keys'), + [ + {code: 107, alt: false, ctrl: false}, + {code: 107, alt: false, ctrl: true}, + {code: 107, alt: true, ctrl: true} + ], 'sendKeys() uses key modifiers'); + }).run(function() { + test.done(); + }); + }); +} + +casper.test.begin('sendKeys() reset option', 1, function(test) { + casper.start('tests/site/form.html', function() { + this.sendKeys('textarea', 'foo'); + this.sendKeys('textarea', 'bar', {reset: true}); + var values = this.getFormValues('form[action="result.html"]'); + test.assertEquals(values.content, "bar"); + }).run(function() { + test.done(); + }); +}); diff --git a/vendor/casperjs/tests/suites/casper/location.js b/vendor/casperjs/tests/suites/casper/location.js new file mode 100755 index 0000000..31cc875 --- /dev/null +++ b/vendor/casperjs/tests/suites/casper/location.js @@ -0,0 +1,23 @@ +/*jshint strict:false*/ +/*global CasperError, casper, console, phantom, require*/ +var utils = require('utils') + +if (utils.ltVersion(phantom.version, '1.8.0')) { + // https://github.com/n1k0/casperjs/issues/101 + casper.warn('document.location is broken under phantomjs < 1.8'); + casper.test.done(); +} else { + casper.test.begin('document.location tests', 1, function(test) { + casper.start('tests/site/index.html', function() { + this.evaluate(function() { + document.location = '/tests/site/form.html'; + }); + }); + casper.then(function() { + test.assertUrlMatches(/form\.html$/, 'document.location works as expected'); + }); + casper.run(function() { + test.done(); + }); + }); +} diff --git a/vendor/casperjs/tests/suites/casper/logging.js b/vendor/casperjs/tests/suites/casper/logging.js new file mode 100755 index 0000000..4537d8d --- /dev/null +++ b/vendor/casperjs/tests/suites/casper/logging.js @@ -0,0 +1,41 @@ +/*jshint strict:false*/ +/*global casper, __utils__*/ +casper.test.begin('logging tests', 4, function(test) { + casper.start('tests/site/index.html'); + + var oldLevel = casper.options.logLevel; + + casper.options.logLevel = 'info'; + casper.options.verbose = false; + + casper.log('foo', 'info'); + casper.test.assert(casper.result.log.some(function(e) { + return e.message === 'foo' && e.level === 'info'; + }), 'Casper.log() adds a log entry'); + + casper.options.logLevel = oldLevel; + casper.options.verbose = true; + + casper.then(function() { + var oldLevel = casper.options.logLevel; + casper.options.logLevel = 'debug'; + casper.options.verbose = false; + casper.evaluate(function() { + __utils__.log('debug message'); + __utils__.log('info message', 'info'); + }); + test.assert(casper.result.log.some(function(e) { + return e.message === 'debug message' && e.level === 'debug' && e.space === 'remote'; + }), 'ClientUtils.log() adds a log entry'); + test.assert(casper.result.log.some(function(e) { + return e.message === 'info message' && e.level === 'info' && e.space === 'remote'; + }), 'ClientUtils.log() adds a log entry at a given level'); + casper.options.logLevel = oldLevel; + casper.options.verbose = true; + }); + + casper.run(function() { + test.assertEquals(this.result.log.length, 3, 'Casper.log() logged messages'); + test.done(); + }); +}); diff --git a/vendor/casperjs/tests/suites/casper/mouseevents.js b/vendor/casperjs/tests/suites/casper/mouseevents.js new file mode 100755 index 0000000..a5e5a84 --- /dev/null +++ b/vendor/casperjs/tests/suites/casper/mouseevents.js @@ -0,0 +1,30 @@ +/*global casper*/ +/*jshint strict:false, maxstatements:99*/ +casper.test.begin('mouseEvent() tests', 16, function(test) { + casper.start('tests/site/mouse-events.html', function() { + test.assert(this.mouseEvent('mousedown', '#test1'), 'Casper.mouseEvent() can dispatch a mousedown event'); + test.assert(this.mouseEvent('mousedown', '#test2'), 'Casper.mouseEvent() can dispatch a mousedown event handled by unobstrusive js'); + test.assert(this.mouseEvent('mouseup', '#test3'), 'Casper.mouseEvent() can dispatch a mouseup event'); + test.assert(this.mouseEvent('mouseup', '#test4'), 'Casper.mouseEvent() can dispatch a mouseup event handled by unobstrusive js'); + test.assert(this.mouseEvent('mouseover', '#test5'), 'Casper.mouseEvent() can dispatch a mouseover event'); + test.assert(this.mouseEvent('mouseover', '#test6'), 'Casper.mouseEvent() can dispatch a mouseover event handled by unobstrusive js'); + test.assert(this.mouseEvent('mouseout', '#test7'), 'Casper.mouseEvent() can dispatch a mouseout event'); + test.assert(this.mouseEvent('mouseout', '#test8'), 'Casper.mouseEvent() can dispatch a mouseout event handled by unobstrusive js'); + }); + + casper.then(function() { + var results = this.getGlobal('results'); + test.assert(results.test1, 'Casper.mouseEvent() triggered mousedown'); + test.assert(results.test2, 'Casper.mouseEvent() triggered mousedown via unobstrusive js'); + test.assert(results.test3, 'Casper.mouseEvent() triggered mouseup'); + test.assert(results.test4, 'Casper.mouseEvent() triggered mouseup via unobstrusive js'); + test.assert(results.test5, 'Casper.mouseEvent() triggered mouseover'); + test.assert(results.test6, 'Casper.mouseEvent() triggered mouseover via unobstrusive js'); + test.assert(results.test7, 'Casper.mouseEvent() triggered mouseout'); + test.assert(results.test8, 'Casper.mouseEvent() triggered mouseout via unobstrusive js'); + }); + + casper.run(function() { + test.done(); + }); +}); diff --git a/vendor/casperjs/tests/suites/casper/navigation.js b/vendor/casperjs/tests/suites/casper/navigation.js new file mode 100755 index 0000000..f7b074c --- /dev/null +++ b/vendor/casperjs/tests/suites/casper/navigation.js @@ -0,0 +1,50 @@ +/*global casper*/ +/*jshint strict:false*/ +var server = require('webserver').create(); +var service = server.listen(8090, function(request, response) { + response.statusCode = 200; + response.setHeader('Content-type', 'text/html'); + response.write('<a href="/link">a link</a>'); + response.write('<form action="/form" method="POST"><input type="submit" /></form>'); + response.close(); +}); + +casper.test.begin('Link Navigation updates response', function(test) { + casper.start('http://localhost:8090', function(response) { + casper.click('a'); + casper.then(function(response) { + test.assertUrlMatch( + /\/link$/, + 'URL matches anchor href' + ); + test.assertEquals( + response.url, + casper.page.url, + 'response is consistent with the internal page' + ); + + }); + }).run(function() { + test.done(); + }); +}); + +casper.test.begin('Form Submittal updates the response', function(test) { + casper.start('http://localhost:8090', function(response) { + casper.fill('form', {}, true); + casper.then(function(response) { + test.assertUrlMatch( + /\/form$/, + 'URL matches form action' + ); + test.assertEquals( + response.url, + casper.page.url, + 'response is consistent with the internal page' + ); + }); + }).run(function() { + test.done(); + server.close(); + }); +}); diff --git a/vendor/casperjs/tests/suites/casper/onerror.js b/vendor/casperjs/tests/suites/casper/onerror.js new file mode 100755 index 0000000..e22ec1a --- /dev/null +++ b/vendor/casperjs/tests/suites/casper/onerror.js @@ -0,0 +1,25 @@ +/*global casper*/ +/*jshint strict:false*/ +casper.test.begin('page.error event tests', 2, function(test) { + var error = {}; + var expectedMessage; + if (phantom.casperEngine === 'phantomjs') { + expectedMessage = "ReferenceError: Can't find variable: plop"; + } + else { + expectedMessage = "ReferenceError: plop is not defined"; + } + casper.once("page.error", function onError(msg, trace) { + error.msg = msg; + error.trace = trace; + }); + casper.start('tests/site/error.html', function() { + test.assertEquals(error.msg, expectedMessage, + "page.error event has been caught OK"); + test.assertMatch(error.trace[0].file, /error.html/, + "page.error retrieves correct stack trace"); + }); + casper.run(function() { + test.done(); + }); +}); diff --git a/vendor/casperjs/tests/suites/casper/open.js b/vendor/casperjs/tests/suites/casper/open.js new file mode 100755 index 0000000..3981163 --- /dev/null +++ b/vendor/casperjs/tests/suites/casper/open.js @@ -0,0 +1,264 @@ +/*global casper*/ +/*jshint strict:false*/ +var usedSettings; + +function onOpen(url, settings) { + usedSettings = settings; +} + +function setUp(test) { + casper.start().on('open', onOpen); +} + +function tearDown(test) { + usedSettings = undefined; + casper.removeListener('open', onOpen); +} + +casper.test.begin('open() GET tests', 2, { + setUp: setUp, + tearDown: tearDown, + test: function(test) { + casper.open('tests/site/index.html').then(function() { + test.pass("Casper.open() can open and load a location using GET"); + test.assertEquals(usedSettings, { + method: "get" + }, "Casper.open() used the expected GET settings"); + }); + + casper.run(function() { + test.done(); + }); + } +}); + +casper.test.begin('open() GET casing tests', 2, { + setUp: setUp, + tearDown: tearDown, + test: function(test) { + casper.open('tests/site/index.html', { + method: 'GET' + }).then(function() { + test.pass("Casper.open() can open and load a location using GET"); + test.assertEquals(usedSettings, { + method: "GET" + }, "Casper.open() used the expected GET settings"); + }); + + casper.run(function() { + test.done(); + }); + } +}); + +casper.test.begin('open() POST tests', 2, { + setUp: setUp, + tearDown: tearDown, + test: function(test) { + casper.open('tests/site/index.html', { + method: 'post', + data: { + plop: 42, + chuck: 'norris' + } + }).then(function() { + test.pass("Casper.open() can open and load a location using POST"); + test.assertEquals(usedSettings, { + method: "post", + data: "plop=42&chuck=norris" + }, "Casper.open() used the expected POST settings"); + }); + + casper.run(function() { + test.done(); + }); + } +}); + +casper.test.begin('open() POST casing tests', 2, { + setUp: setUp, + tearDown: tearDown, + test: function(test) { + casper.open('tests/site/index.html', { + method: 'POST', + data: { + plop: 42, + chuck: 'norris' + } + }).then(function() { + test.pass("Casper.open() can open and load a location using POST"); + test.assertEquals(usedSettings, { + method: "POST", + data: "plop=42&chuck=norris" + }, "Casper.open() used the expected POST settings"); + }); + + casper.run(function() { + test.done(); + }); + } +}); + +casper.test.begin('open() PUT tests', 2, { + setUp: setUp, + tearDown: tearDown, + test: function(test) { + casper.thenOpen('tests/site/index.html', { + method: 'put', + data: { + plop: 42, + chuck: 'norris' + } + }).then(function() { + test.pass("Casper.open() can open and load a location using PUT"); + test.assertEquals(usedSettings, { + method: "put", + data: "plop=42&chuck=norris" + }, "Casper.open() used the expected PUT settings"); + }); + + casper.run(function() { + test.done(); + }); + } +}); + +casper.test.begin('open() PUT casing tests', 2, { + setUp: setUp, + tearDown: tearDown, + test: function(test) { + casper.thenOpen('tests/site/index.html', { + method: 'PUT', + data: { + plop: 42, + chuck: 'norris' + } + }).then(function() { + test.pass("Casper.open() can open and load a location using PUT"); + test.assertEquals(usedSettings, { + method: "PUT", + data: "plop=42&chuck=norris" + }, "Casper.open() used the expected PUT settings"); + }); + + casper.run(function() { + test.done(); + }); + } +}); + +casper.test.begin('open() PUT tests', 2, { + setUp: setUp, + tearDown: tearDown, + test: function(test) { + // HTTP Auth + casper.thenOpen('tests/site/index.html', { + method: 'get', + username: 'bob', + password: 'sinclar' + }).then(function() { + test.pass("Casper.open() can open and load a location using HTTP auth"); + test.assertEquals(usedSettings, { + method: "get", + username: 'bob', + password: 'sinclar' + }, "Casper.open() used the expected HTTP auth settings"); + }); + + casper.run(function() { + test.done(); + }); + } +}); + +casper.test.begin('open() PUT tests', 2, { + setUp: setUp, + tearDown: tearDown, + test: function(test) { + // GET with thenOpen + casper.thenOpen('tests/site/index.html').then(function() { + test.pass("Casper.thenOpen() can open and load a location using GET"); + test.assertEquals(usedSettings, { + method: "get" + }, "Casper.thenOpen() used the expected GET settings"); + }); + + casper.run(function() { + test.done(); + }); + } +}); + +casper.test.begin('open() PUT tests', 2, { + setUp: setUp, + tearDown: tearDown, + test: function(test) { + // POST with thenOpen + casper.thenOpen('tests/site/index.html', { + method: 'post', + data: { + plop: 42, + chuck: 'norris' + } + }, function() { + test.pass("Casper.thenOpen() can open and load a location using POST"); + test.assertEquals(usedSettings, { + method: "post", + data: "plop=42&chuck=norris" + }, "Casper.thenOpen() used the expected POST settings"); + }); + + casper.run(function() { + test.done(); + }); + } +}); + +casper.test.begin('open() PUT tests', 2, { + setUp: setUp, + tearDown: tearDown, + test: function(test) { + // PUT with thenOpen + casper.thenOpen('tests/site/index.html', { + method: 'put', + data: { + plop: 42, + chuck: 'norris' + } + }, function() { + test.pass("Casper.thenOpen() can open and load a location using PUT"); + test.assertEquals(usedSettings, { + method: "put", + data: "plop=42&chuck=norris" + }, "Casper.thenOpen() used the expected PUT settings"); + }); + + casper.run(function() { + test.done(); + }); + } +}); + +casper.test.begin('open() PUT tests', 2, { + setUp: setUp, + tearDown: tearDown, + test: function(test) { + // HTTP Auth with thenOpen + casper.thenOpen('tests/site/index.html', { + method: 'get', + username: 'bob', + password: 'sinclar' + }, function() { + test.pass("Casper.thenOpen() can open and load a location using HTTP auth"); + test.assertEquals(usedSettings, { + method: "get", + username: 'bob', + password: 'sinclar' + }, "Casper.thenOpen() used the expected HTTP auth settings"); + }); + + casper.run(function() { + test.done(); + }); + } +}); diff --git a/vendor/casperjs/tests/suites/casper/popup.js b/vendor/casperjs/tests/suites/casper/popup.js new file mode 100755 index 0000000..ba16a52 --- /dev/null +++ b/vendor/casperjs/tests/suites/casper/popup.js @@ -0,0 +1,91 @@ +/*jshint strict:false, maxstatements:99*/ +/*global CasperError, casper, console, phantom, require*/ +var utils = require('utils'); +var x = require('casper').selectXPath; + +casper.test.begin('popup tests', 22, function(test) { + casper.once('popup.created', function(popup) { + test.pass('"popup.created" event is fired'); + test.assert(utils.isWebPage(popup), + '"popup.created" event callback get a popup page instance'); + }); + + casper.once('popup.loaded', function(popup) { + test.pass('"popup.loaded" event is fired'); + test.assertEquals(popup.evaluate(function() { + return document.title; + }), 'CasperJS test index', + '"popup.loaded" is triggered when popup content is actually loaded'); + }); + + casper.once('popup.closed', function(popup) { + test.assertEquals(this.popups.length, 0, '"popup.closed" event is fired'); + }); + + casper.start('tests/site/popup.html'); + + casper.waitForPopup('index.html', function() { + test.pass('Casper.waitForPopup() waits for a popup being created'); + test.assertEquals(this.popups.length, 1, 'A popup has been added'); + test.assert(utils.isWebPage(this.popups[0]), 'A popup is a WebPage'); + }); + + casper.withPopup('index.html', function() { + test.assertTitle('CasperJS test index', + 'Casper.withPopup() found a popup with expected title'); + test.assertTextExists('three', + 'Casper.withPopup() found a popup with expected text'); + test.assertUrlMatches(/index\.html$/, + 'Casper.withPopup() switched to popup as current active one'); + test.assertEval(function() { + return '__utils__' in window; + }, 'Casper.withPopup() has client utils injected'); + test.assertExists('h1', + 'Casper.withPopup() can perform assertions on the DOM'); + test.assertExists(x('//h1'), + 'Casper.withPopup() can perform assertions on the DOM using XPath'); + }); + + casper.then(function() { + test.assertUrlMatches(/popup\.html$/, + 'Casper.withPopup() has reverted to main page after using the popup'); + }); + + casper.thenClick('.close', function() { + test.assertEquals(this.popups.length, 0, 'Popup is removed when closed'); + }); + + casper.thenOpen('tests/site/popup.html'); + + casper.waitForPopup(/index\.html$/, function() { + test.pass('Casper.waitForPopup() waits for a popup being created'); + }); + + casper.withPopup(/index\.html$/, function() { + test.assertTitle('CasperJS test index', + 'Casper.withPopup() can use a regexp to identify popup'); + }); + + casper.thenClick('.close', function() { + test.assertUrlMatches(/popup\.html$/, + 'Casper.withPopup() has reverted to main page after using the popup'); + test.assertEquals(this.popups.length, 0, 'Popup is removed when closed'); + this.removeAllListeners('popup.created'); + this.removeAllListeners('popup.loaded'); + this.removeAllListeners('popup.closed'); + }); + + casper.thenClick('a[target="_blank"]'); + + casper.waitForPopup('form.html', function() { + test.pass('Casper.waitForPopup() waits when clicked on a link with target=_blank'); + }); + + casper.withPopup('form.html', function() { + test.assertTitle('CasperJS test form'); + }); + + casper.run(function() { + test.done(); + }); +}); diff --git a/vendor/casperjs/tests/suites/casper/prompt.js b/vendor/casperjs/tests/suites/casper/prompt.js new file mode 100755 index 0000000..f77a56d --- /dev/null +++ b/vendor/casperjs/tests/suites/casper/prompt.js @@ -0,0 +1,12 @@ +/*global casper*/ +/*jshint strict:false*/ +casper.test.begin('prompt tests', 1, function(test) { + casper.setFilter('page.prompt', function(message, value) { + return 'Chuck ' + value; + }); + casper.start('tests/site/prompt.html', function() { + test.assertEquals(this.getGlobal('name'), 'Chuck Norris', 'prompted value has been received'); + }).run(function() { + test.done(); + }); +}); diff --git a/vendor/casperjs/tests/suites/casper/request.coffee b/vendor/casperjs/tests/suites/casper/request.coffee new file mode 100755 index 0000000..8f0ad83 --- /dev/null +++ b/vendor/casperjs/tests/suites/casper/request.coffee @@ -0,0 +1,103 @@ +#global casper + +#jshint strict:false + +utils = require "utils" + +if utils.ltVersion(phantom.version, '1.9.0') + casper.test.skip(6, 'PhantomJS version <1.9.0 does not implement request.abort()') + casper.test.done() +else + SERVER = 'http://localhost:54321/' + ORIGINAL_URL = "tests/site/index.html" + CHANGED_URL = "tests/site/index.html?foo=bar" + + setToTrueOnResourceRequested = false + setToTrueOnResourceReceived = false + requestURLRequested = '' + requestURLReceived = '' + + onResourceRequested = (casper, requestData, request) -> + if requestData.url == (SERVER + ORIGINAL_URL) + setToTrueOnResourceRequested = true + requestURLRequested = requestData.url + + onResourceRequestedWithAbort = (casper, requestData, request) -> + if requestData.url == (SERVER + ORIGINAL_URL) + request.abort() + + onResourceRequestedWithChangeURL = (casper, requestData, request) -> + if requestData.url == (SERVER + ORIGINAL_URL) + request.changeUrl(SERVER + CHANGED_URL) + + onResourceReceived = (casper, response) -> + if response.url == (SERVER + ORIGINAL_URL) + setToTrueOnResourceReceived = true + requestURLReceived = response.url + + onResourceReceivedWithChangeURL = (casper, response) -> + if response.url == (SERVER + CHANGED_URL) + requestURLReceived = response.url + + setUp = (test) -> + casper.options.onResourceRequested = onResourceRequested + casper.options.onResourceReceived = onResourceReceived + casper.start() + + setUpWithAbort = (test) -> + casper.options.onResourceRequested = onResourceRequestedWithAbort + casper.options.onResourceReceived = onResourceReceived + casper.start() + + setUpWithChangeURL = (test) -> + casper.options.onResourceRequested = onResourceRequestedWithChangeURL + casper.options.onResourceReceived = onResourceReceivedWithChangeURL + casper.start() + + tearDown = (test) -> + setToTrueOnResourceRequested = false + setToTrueOnResourceReceived = false + casper.options.onResourceRequested = null + casper.options.onResourceReceived = null + + + casper.test.begin "onResourceRequested tests without abort/override", 4, + setUp: setUp + tearDown: tearDown + test: (test) -> + casper.open(ORIGINAL_URL).then -> + + casper.wait 200, -> + test.assertEquals setToTrueOnResourceRequested, true, "Casper.options.onResourceRequested called successfully" + test.assertEquals requestURLRequested, SERVER+ORIGINAL_URL, "request url successfully recorded" + test.assertEquals setToTrueOnResourceReceived, true, "Casper.options.onResourceReceived called successfully" + test.assertEquals requestURLReceived, SERVER+ORIGINAL_URL, "response url successfully recorded" + + casper.run -> + test.done() + + + casper.test.begin "onResourceRequested tests with request.abort()", 1, + setUp: setUpWithAbort + tearDown: tearDown + test: (test) -> + casper.open(ORIGINAL_URL).then -> + + casper.wait 200, -> + test.assertNotEquals setToTrueOnResourceReceived, true, "Casper.options.onResourceReceived correctly never called" + + casper.run -> + test.done() + + + casper.test.begin "onResourceRequested tests with request.changeUrl()", 1, + setUp: setUpWithChangeURL + tearDown: tearDown + test: (test) -> + casper.open(ORIGINAL_URL).then -> + + casper.wait 200, -> + test.assertEquals requestURLReceived, SERVER+CHANGED_URL, "response url successfully changed" + + casper.run -> + test.done() diff --git a/vendor/casperjs/tests/suites/casper/request.js b/vendor/casperjs/tests/suites/casper/request.js new file mode 100755 index 0000000..616faf5 --- /dev/null +++ b/vendor/casperjs/tests/suites/casper/request.js @@ -0,0 +1,48 @@ +/*global casper*/ +/*jshint strict:false*/ +var currentRequest; + +function onResourceRequested(requestData, request) { + currentRequest = requestData; +} + +function testHeader(header) { + return header.name === 'Accept' && header.value === 'application/json'; +} + +casper.test.begin('requests tests', 3, { + setUp: function() { + casper.on('page.resource.requested', onResourceRequested); + }, + + tearDown: function() { + currentRequest = undefined; + casper.removeListener('page.resource.requested', onResourceRequested); + }, + + test: function(test) { + casper.start('tests/site/index.html', function() { + test.assertNot(currentRequest.headers.some(testHeader), + "Casper.open() sets no custom header by default"); + }); + + casper.thenOpen('tests/site/index.html', { + headers: { + Accept: 'application/json' + } + }, function() { + test.assert(currentRequest.headers.some(testHeader), + "Casper.open() can set a custom header"); + }); + + casper.thenOpen('tests/site/index.html', function() { + test.assertNot(currentRequest.headers.some(testHeader), + "Casper.open() custom headers option is not persistent"); + }); + + casper.run(function() { + this.removeAllListeners('page.resource.requested'); + test.done(); + }); + } +}); diff --git a/vendor/casperjs/tests/suites/casper/resources.js b/vendor/casperjs/tests/suites/casper/resources.js new file mode 100755 index 0000000..5805647 --- /dev/null +++ b/vendor/casperjs/tests/suites/casper/resources.js @@ -0,0 +1,35 @@ +/*global casper*/ +/*jshint strict:false*/ +casper.test.begin("Basic resources tests", 5, function(test) { + casper.start("tests/site/resources.html", function() { + test.assertEquals(this.resources.length, 1, "only one resource found"); + }); + + casper.waitForResource("dummy.js", function() { + test.assertEquals(this.resources.length, 2, "two resources found"); + test.assertResourceExists(/dummy\.js/i, "phantom image found via test RegExp"); + test.assertResourceExists(function(res) { + return res.url.match("dummy.js"); + }, "phantom image found via test Function"); + test.assertResourceExists("dummy.js", "phantom image found via test String"); + }, function onTimeout() { + test.fail("waitForResource timeout occured"); + }); + + casper.run(function() { + test.done(); + }); +}); + +casper.test.begin('"resource.error" event', 3, function(test) { + casper.on("resource.error", function(error) { + test.assertType(error, "object", '"resource.error" triggered error information'); + test.assert(error.errorCode === 203, '"resource.error" error code is correct'); + test.assertMatch(error.url, /non-existant\.html$/, '"resource.error" url is correct'); + }); + + casper.start('tests/site/non-existant.html').run(function() { + casper.removeAllListeners("resource.error"); + test.done(); + }); +}); diff --git a/vendor/casperjs/tests/suites/casper/scripts.js b/vendor/casperjs/tests/suites/casper/scripts.js new file mode 100755 index 0000000..d0b44c9 --- /dev/null +++ b/vendor/casperjs/tests/suites/casper/scripts.js @@ -0,0 +1,34 @@ +/*global casper*/ +/*jshint strict:false*/ +casper.test.begin('remote script includes tests', 4, { + setUp: function() { + casper.options.remoteScripts = [ + 'includes/include1.js', // local includes are actually served + 'includes/include2.js' // through the local test webserver + ]; + }, + + tearDown: function() { + casper.options.remoteScripts = []; + }, + + test: function(test) { + casper.start('tests/site/index.html', function() { + test.assertSelectorHasText('#include1', 'include1', + 'Casper.includeRemoteScripts() includes a first remote script on start'); + test.assertSelectorHasText('#include2', 'include2', + 'Casper.includeRemoteScripts() includes a second remote script on start'); + }); + + casper.thenOpen('tests/site/form.html', function() { + test.assertSelectorHasText('#include1', 'include1', + 'Casper.includeRemoteScripts() includes a first remote script on second step'); + test.assertSelectorHasText('#include2', 'include2', + 'Casper.includeRemoteScripts() includes a second remote script on second step'); + }); + + casper.run(function() { + test.done(); + }); + } +}); diff --git a/vendor/casperjs/tests/suites/casper/scroll.js b/vendor/casperjs/tests/suites/casper/scroll.js new file mode 100755 index 0000000..f9a62cb --- /dev/null +++ b/vendor/casperjs/tests/suites/casper/scroll.js @@ -0,0 +1,30 @@ +/*global casper*/ +/*jshint strict:false*/ +casper.test.begin('Casper.scrollTo()', 2, function(test) { + casper.start().then(function() { + this.setContent('<div style="width:2000px;height:2000px">large div is large</div>'); + this.scrollTo(1000, 1000); + test.assertEquals(this.getGlobal("scrollX"), 1000, "scrollTo() scrolls to X position"); + test.assertEquals(this.getGlobal("scrollY"), 1000, "scrollTo() scrolls to Y position"); + }); + + casper.run(function() { + test.done(); + }); +}); + + +casper.test.begin('Casper.scrollToBottom()', 1, function(test) { + casper.start().then(function() { + this.setContent('<div style="height:2000px">long div is long</div>'); + this.scrollToBottom(); + test.assertEval(function() { + /*global __utils__*/ + return __utils__.getDocumentHeight() - window.innerHeight === window.scrollY; + }, "scrollToBottom() scrolls to max Y by default"); + }); + + casper.run(function() { + test.done(); + }); +}); diff --git a/vendor/casperjs/tests/suites/casper/start.js b/vendor/casperjs/tests/suites/casper/start.js new file mode 100755 index 0000000..c80a2e5 --- /dev/null +++ b/vendor/casperjs/tests/suites/casper/start.js @@ -0,0 +1,17 @@ +/*global casper*/ +/*jshint strict:false*/ +casper.test.begin('start() tests', 4, function(test) { + casper.start('tests/site/index.html', function() { + test.pass('Casper.start() can chain a next step'); + test.assertTitle('CasperJS test index', 'Casper.start() opened the passed url'); + test.assertEval(function() { + return typeof(__utils__) === "object"; + }, 'Casper.start() injects ClientUtils instance within remote DOM'); + }); + + test.assert(casper.started, 'Casper.start() started'); + + casper.run(function() { + test.done(); + }); +}); diff --git a/vendor/casperjs/tests/suites/casper/steps.js b/vendor/casperjs/tests/suites/casper/steps.js new file mode 100755 index 0000000..b4d020e --- /dev/null +++ b/vendor/casperjs/tests/suites/casper/steps.js @@ -0,0 +1,54 @@ +/*global casper*/ +/*jshint strict:false*/ +casper.test.begin('steps tests', 8, function(test) { + casper.start('tests/site/index.html'); + + var nsteps = casper.steps.length; + + casper.then(function(response) { + test.assertTitle('CasperJS test index', + 'Casper.then() added a new step'); + }); + + test.assertEquals(casper.steps.length, nsteps + 1, + 'Casper.then() can add a new step'); + + casper.thenOpen('tests/site/test.html'); + + test.assertEquals(casper.steps.length, nsteps + 2, + 'Casper.thenOpen() can add a new step'); + + casper.thenOpen('tests/site/test.html', function() { + test.assertTitle('CasperJS test target', + 'Casper.thenOpen() opened a location and executed a step'); + }); + + test.assertEquals(casper.steps.length, nsteps + 4, + 'Casper.thenOpen() can add a new step for opening, plus another step'); + + casper.each([1, 2, 3], function(self, item, i) { + test.assertEquals(i, item - 1, + 'Casper.each() passes a contextualized index'); + }); + + casper.run(function() { + test.done(); + }); +}); + +casper.test.begin('eachThen() tests', 1, function(test) { + var received = []; + + casper.start().eachThen([1, 2, 3], function(response) { + if (!response) { + test.fail('No response received'); + } + received.push(response.data); + }); + + casper.run(function() { + test.assertEquals(received, [1, 2, 3], + 'Casper.eachThen() passes item to step data'); + test.done(); + }); +}); diff --git a/vendor/casperjs/tests/suites/casper/urls.js b/vendor/casperjs/tests/suites/casper/urls.js new file mode 100755 index 0000000..5d36b2a --- /dev/null +++ b/vendor/casperjs/tests/suites/casper/urls.js @@ -0,0 +1,25 @@ +/*global casper*/ +/*jshint strict:false*/ +casper.test.begin('urls tests', 6, function(test) { + casper.start('tests/site/urls.html', function() { + this.clickLabel('raw unicode', 'a'); + }); + + casper.then(function() { + test.assertHttpStatus(200); + test.assertUrlMatches('Forlì', 'Casper.getCurrentUrl() retrieves a raw unicode URL'); + this.clickLabel('escaped', 'a'); + }); + + casper.then(function() { + test.assertHttpStatus(200); + test.assertUrlMatches('Forlì', 'Casper.getCurrentUrl() retrieves an escaped URL'); + this.clickLabel('uri encoded', 'a'); + }); + + casper.run(function() { + test.assertHttpStatus(200); + test.assertUrlMatches('Forlì', 'Casper.getCurrentUrl() retrieves a decoded URL'); + test.done(); + }); +}); diff --git a/vendor/casperjs/tests/suites/casper/viewport.js b/vendor/casperjs/tests/suites/casper/viewport.js new file mode 100755 index 0000000..c0df689 --- /dev/null +++ b/vendor/casperjs/tests/suites/casper/viewport.js @@ -0,0 +1,41 @@ +/*global casper*/ +/*jshint strict:false*/ +var utils = require('utils'); + +casper.test.begin('viewport() tests', 3, function(test) { + casper.start(); + casper.viewport(1337, 999); + test.assertEquals(casper.page.viewportSize.width, 1337, + 'Casper.viewport() can change the width of page viewport'); + test.assertEquals(casper.page.viewportSize.height, 999, + 'Casper.viewport() can change the height of page viewport'); + test.assertRaises(casper.viewport, ['a', 'b'], + 'Casper.viewport() validates viewport size data'); + test.done(); +}); + +casper.test.begin('viewport() asynchronous tests', 2, function(test) { + var screenshotData; + + casper.start('tests/site/index.html').viewport(800, 600, function() { + this.setContent(utils.format('<img src="data:image/png;base64,%s">', + this.captureBase64('png'))); + }); + + casper.then(function() { + var imgInfo = this.getElementInfo('img'); + if (phantom.casperEngine === "slimerjs" && imgInfo.width !== 800) { + // sometimes, setting viewport could take more time in slimerjs/gecko + // and the image is not still ready: :-/ + test.skip(2); + } + else { + test.assertEquals(imgInfo.width, 800, 'Casper.viewport() changes width asynchronously'); + test.assertEquals(imgInfo.height, 600, 'Casper.viewport() changes height asynchronously'); + } + }); + + casper.run(function() { + test.done(); + }); +}); diff --git a/vendor/casperjs/tests/suites/casper/visible.js b/vendor/casperjs/tests/suites/casper/visible.js new file mode 100755 index 0000000..accc451 --- /dev/null +++ b/vendor/casperjs/tests/suites/casper/visible.js @@ -0,0 +1,19 @@ +/*global casper*/ +/*jshint strict:false*/ +casper.test.begin('visibility tests', 5, function(test) { + casper.start('tests/site/visible.html', function() { + test.assert(!this.visible('#img1'), 'Casper.visible() can detect if an element is invisible'); + test.assert(this.visible('#img2'), 'Casper.visible() can detect if an element is visible'); + test.assert(!this.visible('#img3'), 'Casper.visible() can detect if an element is invisible'); + test.assert(this.visible('img'), 'Casper.visible() can detect if an element is visible'); + this.waitWhileVisible('#img1', function() { + test.pass('Casper.waitWhileVisible() can wait while an element is visible'); + }, function() { + test.fail('Casper.waitWhileVisible() can wait while an element is visible'); + }, 2000); + }); + + casper.run(function() { + test.done(); + }); +}); diff --git a/vendor/casperjs/tests/suites/casper/wait.js b/vendor/casperjs/tests/suites/casper/wait.js new file mode 100755 index 0000000..dcf0823 --- /dev/null +++ b/vendor/casperjs/tests/suites/casper/wait.js @@ -0,0 +1,170 @@ +/*global casper*/ +/*jshint strict:false*/ +casper.test.begin('wait() tests', 1, function(test) { + var waitStart; + + casper.start('tests/site/index.html', function() { + waitStart = new Date().getTime(); + }); + + casper.wait(250, function() { + test.assert(new Date().getTime() - waitStart > 250, + 'Casper.wait() can wait for a given amount of time'); + }); + + casper.run(function() { + test.done(); + }); +}); + +casper.test.begin('waitFor() tests', 2, function(test) { + casper.start('tests/site/waitFor.html'); + + casper.waitFor(function() { + return this.evaluate(function() { + return document.querySelectorAll('li').length === 4; + }); + }, function() { + test.pass('Casper.waitFor() can wait for something to happen'); + }, function() { + test.fail('Casper.waitFor() can wait for something to happen'); + }); + + casper.reload().waitFor(function(){ + return false; + }, function() { + test.fail('waitFor() processes onTimeout callback'); + }, function() { + test.pass('waitFor() processes onTimeout callback'); + }, 1000); + + casper.run(function() { + test.done(); + }); +}); + +casper.test.begin('waitForResource() tests', 2, function(test) { + casper.start('tests/site/waitFor.html'); + + casper.waitForResource('phantom.png', function() { + test.pass('Casper.waitForResource() waits for a resource'); + }, function() { + test.fail('Casper.waitForResource() waits for a resource'); + }); + + casper.reload().waitForResource(/phantom\.png$/, function() { + test.pass('Casper.waitForResource() waits for a resource using RegExp'); + }, function() { + test.fail('Casper.waitForResource() waits for a resource using RegExp'); + }); + + casper.run(function() { + test.done(); + }); +}); + +casper.test.begin('waitForSelector() tests', 1, function(test) { + casper.start('tests/site/waitFor.html'); + + casper.waitForSelector('li:nth-child(4)', function() { + test.pass('Casper.waitForSelector() waits for a selector to exist'); + }, function() { + test.fail('Casper.waitForSelector() waits for a selector to exist'); + }); + + casper.run(function() { + test.done(); + }); +}); + +casper.test.begin('waitForText() tests', 3, function(test) { + casper.start('tests/site/waitFor.html'); + + casper.waitForText('<li>four</li>', function() { + test.pass('Casper.waitForText() can wait for text'); + }, function() { + test.fail('Casper.waitForText() can wait for text'); + }); + + casper.reload().waitForText(/four/i, function() { + test.pass('Casper.waitForText() can wait for regexp'); + }, function() { + test.fail('Casper.waitForText() can wait for regexp'); + }); + + casper.reload().waitForText('Voilà', function() { + test.pass('Casper.waitForText() can wait for decoded HTML text'); + }, function() { + test.fail('Casper.waitForText() can wait for decoded HTML text'); + }, 1000); + + casper.run(function() { + test.done(); + }); +}); + +casper.test.begin('waitForSelectorTextChange() tests', 1, function(test) { + casper.start('tests/site/waitFor.html'); + + casper.waitForSelectorTextChange('#textChange', function() { + test.pass('Casper.waitForSelectorTextChange() can wait for text on a selector to change'); + }, function() { + test.fail('Casper.waitForSelectorTextChange() can wait for text on a selector to change'); + }); + + casper.run(function() { + test.done(); + }); +}); + +casper.test.begin('waitUntilVisible() tests', 2, function(test) { + casper.start('tests/site/waitFor.html'); + + casper.waitUntilVisible('li:nth-child(4)', function() { + test.pass('Casper.waitUntilVisible() waits for a selector being visible'); + }, function() { + test.fail('Casper.waitUntilVisible() waits for a selector being visible'); + }); + + casper.waitUntilVisible('p', function() { + test.pass('Casper.waitUntilVisible() waits for a selector being visible'); + }, function() { + test.fail('Casper.waitUntilVisible() waits for a selector being visible'); + }); + + casper.run(function() { + test.done(); + }); +}); + +casper.test.begin('waitForUrl() regexp tests', 1, function(test) { + casper.start().thenEvaluate(function() { + setTimeout(function() { + document.location = './form.html'; + }, 100); + }); + + casper.waitForUrl(/form\.html$/, function() { + test.pass('Casper.waitForUrl() waits for a given regexp url'); + }); + + casper.run(function() { + test.done(); + }); +}); + +casper.test.begin('waitForUrl() string tests', 1, function(test) { + casper.start().thenEvaluate(function() { + setTimeout(function() { + document.location = './form.html'; + }, 100); + }); + + casper.waitForUrl('form.html', function() { + test.pass('Casper.waitForUrl() waits for a given string url'); + }); + + casper.run(function() { + test.done(); + }); +}); diff --git a/vendor/casperjs/tests/suites/casper/xpath.js b/vendor/casperjs/tests/suites/casper/xpath.js new file mode 100755 index 0000000..81b08d7 --- /dev/null +++ b/vendor/casperjs/tests/suites/casper/xpath.js @@ -0,0 +1,34 @@ +/*global casper, __utils__*/ +/*jshint strict:false*/ +var x = require('casper').selectXPath; + +casper.test.begin('XPath tests', 6, function(test) { + casper.start('tests/site/index.html', function() { + test.assertExists({ + type: 'xpath', + path: '/html/body/ul/li[2]' + }, 'XPath selector can find an element'); + test.assertDoesntExist({ + type: 'xpath', + path: '/html/body/ol/li[2]' + }, 'XPath selector does not retrieve a nonexistent element'); + test.assertExists(x('/html/body/ul/li[2]'), 'selectXPath() shortcut can find an element as well'); + test.assertEvalEquals(function() { + return __utils__.findAll({type: 'xpath', path: '/html/body/ul/li'}).length; + }, 3, 'Correct number of elements are found'); + }); + + casper.thenClick(x('/html/body/a[2]'), function() { + test.assertTitle('CasperJS test form', 'Clicking XPath works as expected'); + this.fill(x('/html/body/form'), { + email: 'chuck@norris.com' + }); + test.assertEvalEquals(function() { + return document.querySelector('input[name="email"]').value; + }, 'chuck@norris.com', 'Casper.fill() can fill an input[type=text] form field'); + }); + + casper.run(function() { + test.done(); + }); +}); diff --git a/vendor/casperjs/tests/suites/cli.js b/vendor/casperjs/tests/suites/cli.js new file mode 100755 index 0000000..feb6b28 --- /dev/null +++ b/vendor/casperjs/tests/suites/cli.js @@ -0,0 +1,158 @@ +/*global casper*/ +/*jshint strict:false, maxstatements:99*/ +var cli = require('cli'); + +casper.test.begin('parsing an empty argument list', 12, function(test) { + var parsed = cli.parse([]); + // clean + test.assertEquals(parsed.args, [], 'parse() returns expected positional args array'); + test.assertEquals(parsed.options, {}, 'parse() returns expected options object'); + test.assertEquals(parsed.get(0), undefined, 'parse() does not return inexistant positional arg'); + test.assertEquals(parsed.get('blah'), undefined, 'parse() does not return inexistant option'); + test.assert(!parsed.has(0), 'has() checks if an arg is set'); + test.assert(!parsed.has('blah'), 'has() checks if an option is set'); + // raw + test.assertEquals(parsed.raw.args, [], 'parse() returns expected positional args array'); + test.assertEquals(parsed.raw.options, {}, 'parse() returns expected options object'); + test.assertEquals(parsed.raw.get(0), undefined, 'parse() does not return inexistant positional arg'); + test.assertEquals(parsed.raw.get('blah'), undefined, 'parse() does not return inexistant option'); + test.assert(!parsed.raw.has(0), 'has() checks if a raw arg is set'); + test.assert(!parsed.raw.has('blah'), 'has() checks if a raw option is set'); + test.done(); +}); + +casper.test.begin('parsing an basic argument list', 14, function(test) { + var parsed = cli.parse(['foo', 'bar']); + // clean + test.assertEquals(parsed.args, ['foo', 'bar'], 'parse() returns expected positional args array'); + test.assertEquals(parsed.options, {}, 'parse() returns expected options object'); + test.assertEquals(parsed.get(0), 'foo', 'parse() retrieve first positional arg'); + test.assertEquals(parsed.get(1), 'bar', 'parse() retrieve second positional arg'); + test.assert(parsed.has(0), 'has() checks if an arg is set'); + test.assert(parsed.has(1), 'has() checks if an arg is set'); + test.assert(!parsed.has(2), 'has() checks if an arg is not set'); + // raw + test.assertEquals(parsed.raw.args, ['foo', 'bar'], 'parse() returns expected positional raw args array'); + test.assertEquals(parsed.raw.options, {}, 'parse() returns expected raw options object'); + test.assertEquals(parsed.raw.get(0), 'foo', 'parse() retrieve first positional raw arg'); + test.assertEquals(parsed.raw.get(1), 'bar', 'parse() retrieve second positional raw arg'); + test.assert(parsed.raw.has(0), 'has() checks if a arw arg is set'); + test.assert(parsed.raw.has(1), 'has() checks if a arw arg is set'); + test.assert(!parsed.raw.has(2), 'has() checks if a arw arg is not set'); + test.done(); +}); + +casper.test.begin('parsing some options', 12, function(test) { + var parsed = cli.parse(['--foo=bar', '--baz']); + // clean + test.assertEquals(parsed.args, [], 'parse() returns expected positional args array'); + test.assertEquals(parsed.options, {foo: 'bar', baz: true}, 'parse() returns expected options object'); + test.assertEquals(parsed.get('foo'), 'bar', 'parse() retrieve an option value'); + test.assert(parsed.get('baz'), 'parse() retrieve boolean option flag'); + test.assert(parsed.has("foo"), 'has() checks if an option is set'); + test.assert(parsed.has("baz"), 'has() checks if an option is set'); + // raw + test.assertEquals(parsed.raw.args, [], 'parse() returns expected positional raw args array'); + test.assertEquals(parsed.raw.options, {foo: 'bar', baz: true}, 'parse() returns expected options raw object'); + test.assertEquals(parsed.raw.get('foo'), 'bar', 'parse() retrieve an option raw value'); + test.assert(parsed.raw.get('baz'), 'parse() retrieve boolean raw option flag'); + test.assert(parsed.raw.has("foo"), 'has() checks if a raw option is set'); + test.assert(parsed.raw.has("baz"), 'has() checks if a raw option is set'); + test.done(); +}); + +casper.test.begin('parsing an empty argument list', 8, function(test) { + var parsed = cli.parse(['--&é"à=42===42']); + // clean + test.assertEquals(parsed.args, [], 'parse() returns expected positional args array'); + test.assertEquals(parsed.options, { '&é"à': "42===42" }, 'parse() returns expected options object'); + test.assertEquals(parsed.get('&é"à'), "42===42", 'parse() handles options with exotic names'); + test.assert(parsed.has('&é"à'), 'has() checks if an option is set'); + // raw + test.assertEquals(parsed.raw.args, [], 'parse() returns expected positional raw args array'); + test.assertEquals(parsed.raw.options, { '&é"à': "42===42" }, 'parse() returns expected options raw object'); + test.assertEquals(parsed.raw.get('&é"à'), "42===42", 'parse() handles raw options with exotic names'); + test.assert(parsed.raw.has('&é"à'), 'has() checks if a raw option is set'); + test.done(); +}); + +casper.test.begin('parsing commands containing args and options', 34, function(test) { + var parsed = cli.parse(['foo & bar', 'baz & boz', '--universe=42', + '--lap=13.37', '--chucknorris', '--oops=false']); + // clean + test.assertEquals(parsed.args, ['foo & bar', 'baz & boz'], 'parse() returns expected positional args array'); + test.assertEquals(parsed.options, { + universe: 42, + lap: 13.37, + chucknorris: true, + oops: false }, 'parse() returns expected options object'); + test.assertEquals(parsed.get('universe'), 42, 'parse() can cast a numeric option value'); + test.assertEquals(parsed.get('lap'), 13.37, 'parse() can cast a float option value'); + test.assertType(parsed.get('lap'), "number", 'parse() can cast a boolean value'); + test.assert(parsed.get('chucknorris'), 'parse() can get a flag value by its option name'); + test.assertType(parsed.get('oops'), "boolean", 'parse() can cast a boolean value'); + test.assertEquals(parsed.get('oops'), false, 'parse() can cast a boolean value'); + test.assert(parsed.has(0), 'has() checks if an arg is set'); + test.assert(parsed.has(1), 'has() checks if an arg is set'); + test.assert(parsed.has("universe"), 'has() checks if an option is set'); + test.assert(parsed.has("lap"), 'has() checks if an option is set'); + test.assert(parsed.has("chucknorris"), 'has() checks if an option is set'); + test.assert(parsed.has("oops"), 'has() checks if an option is set'); + + // drop() + parsed.drop(0); + test.assertEquals(parsed.get(0), 'baz & boz', 'drop() dropped arg'); + parsed.drop("universe"); + test.assert(!parsed.has("universe"), 'drop() dropped option'); + test.assert(!parsed.raw.has("universe"), 'drop() dropped raw option'); + test.assertEquals(parsed.args, ["baz & boz"], 'drop() did not affect other args'); + test.assertEquals(parsed.options, { + lap: 13.37, + chucknorris: true, + oops: false + }, 'drop() did not affect other options'); + + // raw + test.assertEquals(parsed.args.length, parsed.raw.args.length, + 'parse() cast and raw args share same length'); + test.assertEquals(Object.keys(parsed.options).length, Object.keys(parsed.raw.options).length, + 'parse() cast and raw options share same length'); + test.assertEquals(parsed.raw.args, ['baz & boz'], + 'parse() returns expected positional raw args array'); + test.assertEquals(parsed.raw.options, { + lap: "13.37", + chucknorris: true, + oops: "false" + }, 'parse() returns expected options raw object'); + test.assertEquals(parsed.raw.get('lap'), "13.37", 'parse() does not cast a raw float option value'); + test.assertType(parsed.raw.get('lap'), "string", 'parse() does not cast a numeric value'); + test.assert(parsed.raw.get('chucknorris'), 'parse() can get a flag value by its option name'); + test.assertType(parsed.raw.get('oops'), "string", 'parse() can cast a boolean value'); + test.assertEquals(parsed.raw.get('oops'), "false", 'parse() can cast a boolean value'); + + // drop() for raw + parsed.raw.drop(0); + test.assertEquals(parsed.raw.get(0), undefined, 'drop() dropped raw arg'); + parsed.raw.drop("universe"); + test.assert(!parsed.raw.has("universe"), 'drop() dropped raw option'); + test.assertEquals(parsed.raw.args, [], 'drop() did not affect other raw args'); + test.assertEquals(parsed.raw.options, { + lap: "13.37", + chucknorris: true, + oops: "false" + }, 'drop() did not affect other raw options'); + parsed.raw.drop("lap"); + test.assert(!parsed.raw.has("lap"), 'drop() dropped raw option'); + test.assert(!parsed.has("lap"), 'drop() dropped cast option as well'); + + test.done(); +}); + +casper.test.begin('default values', 2, function(test) { + var parsed = cli.parse(['foo', '--bar']); + test.assertEquals(parsed.get(42, 'boz'), 'boz', + 'get() can return a default arg value'); + test.assertEquals(parsed.get('--zorg', 'boz'), 'boz', + 'get() can return a default option value'); + test.done(); +}); diff --git a/vendor/casperjs/tests/suites/clientutils.js b/vendor/casperjs/tests/suites/clientutils.js new file mode 100755 index 0000000..5ba6977 --- /dev/null +++ b/vendor/casperjs/tests/suites/clientutils.js @@ -0,0 +1,203 @@ +/*global casper*/ +/*jshint strict:false*/ +var fs = require('fs'); +var x = require('casper').selectXPath; + +function fakeDocument(html) { + window.document.body.innerHTML = html; +} + +casper.test.begin('ClientUtils.encode() tests', 6, function(test) { + var clientutils = require('clientutils').create(), + testCases = { + 'an empty string': '', + 'a word': 'plop', + 'a null char': 'a\u0000', + 'an utf8 string': 'ÀÁÃÄÅÇÈÉÊËÌÍÎÏÒÓÔÕÖÙÚÛÜÝàáâãäåçèéêëìíîïðòóôõöùúûüýÿ', + 'song lyrics': ("Voilà l'été, j'aperçois le soleil\n" + + "Les nuages filent et le ciel s'éclaircit\n" + + "Et dans ma tête qui bourdonnent?\n" + + "Les abeilles!"), + 'a file contents': fs.read(phantom.casperPath + '/tests/site/alert.html') + }; + for (var what in testCases) { + test.assertEquals( + clientutils.decode(clientutils.encode(testCases[what])), + testCases[what], + 'ClientUtils.encode() encodes and decodes ' + what + ); + } + test.done(); +}); + +casper.test.begin('ClientUtils.exists() tests', 5, function(test) { + var clientutils = require('clientutils').create(); + fakeDocument('<ul class="foo"><li>bar</li><li>baz</li></ul>'); + test.assert(clientutils.exists('ul'), + 'ClientUtils.exists() checks that an element exist'); + test.assertNot(clientutils.exists('ol'), + 'ClientUtils.exists() checks that an element exist'); + test.assert(clientutils.exists('ul.foo li'), + 'ClientUtils.exists() checks that an element exist'); + // xpath + test.assert(clientutils.exists(x('//ul')), + 'ClientUtils.exists() checks that an element exist using XPath'); + test.assertNot(clientutils.exists(x('//ol')), + 'ClientUtils.exists() checks that an element exist using XPath'); + fakeDocument(null); + test.done(); +}); + +casper.test.begin('ClientUtils.findAll() tests', 7, function(test) { + var clientutils = require('clientutils').create(); + fakeDocument('<ul class="foo"><li>bar</li><li>baz</li></ul>'); + test.assertType(clientutils.findAll('li'), 'array', + 'ClientUtils.findAll() can find matching DOM elements'); + test.assertEquals(clientutils.findAll('li').length, 2, + 'ClientUtils.findAll() can find matching DOM elements'); + test.assertType(clientutils.findAll('ol'), 'array', + 'ClientUtils.findAll() can find matching DOM elements'); + test.assertEquals(clientutils.findAll('ol').length, 0, + 'ClientUtils.findAll() can find matching DOM elements'); + // scoped + var scope = clientutils.findOne('ul'); + test.assertType(clientutils.findAll('li', scope), 'array', + 'ClientUtils.findAll() can find matching DOM elements within a given scope'); + test.assertEquals(clientutils.findAll('li', scope).length, 2, + 'ClientUtils.findAll() can find matching DOM elements within a given scope'); + test.assertType(clientutils.findAll(x('//li'), scope), 'array', + 'ClientUtils.findAll() can find matching DOM elements using XPath within a given scope'); + fakeDocument(null); + test.done(); +}); + +casper.test.begin('ClientUtils.findOne() tests', 4, function(test) { + var clientutils = require('clientutils').create(); + fakeDocument('<ul class="foo"><li>bar</li><li>baz</li></ul>'); + test.assertType(clientutils.findOne('ul'), 'htmlulistelement', + 'ClientUtils.findOne() can find a matching DOM element'); + test.assertNot(clientutils.findOne('ol'), + 'ClientUtils.findOne() can find a matching DOM element'); + // scoped + var scope = clientutils.findOne('ul'); + test.assertType(clientutils.findOne('li', scope), 'htmllielement', + 'ClientUtils.findOne() can find a matching DOM element within a given scope'); + test.assertType(clientutils.findOne(x('//li'), scope), 'htmllielement', + 'ClientUtils.findOne() can find a matching DOM element using XPath within a given scope'); + fakeDocument(null); + test.done(); +}); + + +casper.test.begin('ClientUtils.processSelector() tests', 6, function(test) { + var clientutils = require('clientutils').create(); + // CSS3 selector + var cssSelector = clientutils.processSelector('html body > ul.foo li'); + test.assertType(cssSelector, 'object', + 'ClientUtils.processSelector() can process a CSS3 selector'); + test.assertEquals(cssSelector.type, 'css', + 'ClientUtils.processSelector() can process a CSS3 selector'); + test.assertEquals(cssSelector.path, 'html body > ul.foo li', + 'ClientUtils.processSelector() can process a CSS3 selector'); + // XPath selector + var xpathSelector = clientutils.processSelector(x('//li[text()="blah"]')); + test.assertType(xpathSelector, 'object', + 'ClientUtils.processSelector() can process a XPath selector'); + test.assertEquals(xpathSelector.type, 'xpath', + 'ClientUtils.processSelector() can process a XPath selector'); + test.assertEquals(xpathSelector.path, '//li[text()="blah"]', + 'ClientUtils.processSelector() can process a XPath selector'); + test.done(); +}); + +casper.test.begin('ClientUtils.getElementBounds() tests', 3, function(test) { + casper.start().then(function() { + this.page.content = '<div id="b1" style="position:fixed;top:10px;left:11px;width:50px;height:60px"></div>'; + test.assertEquals( + this.getElementBounds('#b1'), + { top: 10, left: 11, width: 50, height: 60 }, + 'ClientUtils.getElementBounds() retrieves element boundaries' + ); + }); + casper.then(function() { + var html = '<div id="boxes">'; + html += ' <div style="position:fixed;top:10px;left:11px;width:50px;height:60px"></div>'; + html += ' <div style="position:fixed;top:20px;left:21px;width:70px;height:80px"></div>'; + html += '</div>'; + this.page.content = html; + var bounds = this.getElementsBounds('#boxes div'); + test.assertEquals( + bounds[0], + { top: 10, left: 11, width: 50, height: 60 }, + 'ClientUtils.getElementsBounds() retrieves multiple elements boundaries' + ); + test.assertEquals( + bounds[1], + { top: 20, left: 21, width: 70, height: 80 }, + 'ClientUtils.getElementsBounds() retrieves multiple elements boundaries' + ); + }); + casper.run(function() { + test.done(); + }); +}); + +casper.test.begin('ClientUtils.getElementInfo() tests', 10, function(test) { + casper.page.content = '<a href="plop" class="plip plup"><i>paf</i></a>'; + var info = casper.getElementInfo('a.plip'); + test.assertEquals(info.nodeName, 'a', 'ClientUtils.getElementInfo() retrieves element name'); + test.assertEquals(info.attributes, { + 'href': 'plop', + 'class': 'plip plup' + }, 'ClientUtils.getElementInfo() retrieves element attributes'); + test.assertEquals(info.html, '<i>paf</i>', 'ClientUtils.getElementInfo() retrieves element html content'); + test.assertEquals(info.text, 'paf', 'ClientUtils.getElementInfo() retrieves element text'); + test.assert(info.x > 0, 'ClientUtils.getElementInfo() retrieves element x pos'); + test.assert(info.y > 0, 'ClientUtils.getElementInfo() retrieves element y pos'); + test.assert(info.width > 0, 'ClientUtils.getElementInfo() retrieves element width'); + test.assert(info.height > 0, 'ClientUtils.getElementInfo() retrieves element height'); + test.assert(info.visible, 'ClientUtils.getElementInfo() retrieves element visibility'); + test.assertEquals(info.tag, '<a href="plop" class="plip plup"><i>paf</i></a>', + 'ClientUtils.getElementInfo() retrieves element whole tag contents'); + test.done(); +}); + +casper.test.begin('ClientUtils.getElementsInfo() first element tests', 10, function(test) { + casper.page.content = '<a href="plop" class="plip plup"><i>paf</i></a><a href="plap" class="plip plup"><i>puf</i></a>'; + var info = casper.getElementsInfo('a.plip'); + test.assertEquals(info[0].nodeName, 'a', 'ClientUtils.getElementsInfo() retrieves first element name'); + test.assertEquals(info[0].attributes, { + 'href': 'plop', + 'class': 'plip plup' + }, 'ClientUtils.getElementsInfo() retrieves first element attributes'); + test.assertEquals(info[0].html, '<i>paf</i>', 'ClientUtils.getElementsInfo() retrieves first element html content'); + test.assertEquals(info[0].text, 'paf', 'ClientUtils.getElementsInfo() retrieves first element text'); + test.assert(info[0].x > 0, 'ClientUtils.getElementsInfo() retrieves first element x pos'); + test.assert(info[0].y > 0, 'ClientUtils.getElementsInfo() retrieves first element y pos'); + test.assert(info[0].width > 0, 'ClientUtils.getElementsInfo() retrieves first element width'); + test.assert(info[0].height > 0, 'ClientUtils.getElementsInfo() retrieves first element height'); + test.assert(info[0].visible, 'ClientUtils.getElementsInfo() retrieves first element visibility'); + test.assertEquals(info[0].tag, '<a href="plop" class="plip plup"><i>paf</i></a>', + 'ClientUtils.getElementsInfo() retrieves first element whole tag contents'); + test.done(); +}); + +casper.test.begin('ClientUtils.getElementsInfo() second element tests', 10, function(test) { + casper.page.content = '<a href="plop" class="plip plup"><i>paf</i></a><a href="plap" class="plip plup"><i>puf</i></a>'; + var info = casper.getElementsInfo('a.plip'); + test.assertEquals(info[1].nodeName, 'a', 'ClientUtils.getElementsInfo() retrieves second element name'); + test.assertEquals(info[1].attributes, { + 'href': 'plap', + 'class': 'plip plup' + }, 'ClientUtils.getElementsInfo() retrieves second element attributes'); + test.assertEquals(info[1].html, '<i>puf</i>', 'ClientUtils.getElementsInfo() retrieves second element html content'); + test.assertEquals(info[1].text, 'puf', 'ClientUtils.getElementsInfo() retrieves second element text'); + test.assert(info[1].x > 0, 'ClientUtils.getElementsInfo() retrieves second element x pos'); + test.assert(info[1].y > 0, 'ClientUtils.getElementsInfo() retrieves second element y pos'); + test.assert(info[1].width > 0, 'ClientUtils.getElementsInfo() retrieves second element width'); + test.assert(info[1].height > 0, 'ClientUtils.getElementsInfo() retrieves second element height'); + test.assert(info[1].visible, 'ClientUtils.getElementsInfo() retrieves second element visibility'); + test.assertEquals(info[1].tag, '<a href="plap" class="plip plup"><i>puf</i></a>', + 'ClientUtils.getElementsInfo() retrieves second element whole tag contents'); + test.done(); +}); diff --git a/vendor/casperjs/tests/suites/coffee.coffee b/vendor/casperjs/tests/suites/coffee.coffee new file mode 100755 index 0000000..9de230b --- /dev/null +++ b/vendor/casperjs/tests/suites/coffee.coffee @@ -0,0 +1,20 @@ +"A small subset of the run.js written in coffeescript" + +steps = 0 + +casper.options.onStepComplete = -> steps++ + +casper.test.begin "writing async tests in coffeescript", 4, (test) -> + casper.start "tests/site/index.html", -> + test.assertTitle "CasperJS test index", "Casper.start() casper can start itself an open an url" + test.assertEquals @fetchText("ul li"), "onetwothree", "Casper.fetchText() can retrieves text contents" + @click "a[href=\"test.html\"]" + + casper.then -> + test.assertTitle "CasperJS test target", "Casper.click() casper can click on a text link" + @click "a[href=\"form.html\"]" + + casper.run -> + test.assertEquals steps, 3, "Casper.options.onStepComplete() is called on step complete" + @options.onStepComplete = null + @test.done() diff --git a/vendor/casperjs/tests/suites/fs.js b/vendor/casperjs/tests/suites/fs.js new file mode 100755 index 0000000..46b5881 --- /dev/null +++ b/vendor/casperjs/tests/suites/fs.js @@ -0,0 +1,35 @@ +/*global casper*/ +/*jshint strict:false*/ +var fs = require('fs'); + +casper.test.begin('fs.dirname() tests', 8, function(test) { + var tests = { + '/local/plop/foo.js': '/local/plop', + 'local/plop/foo.js': 'local/plop', + './local/plop/foo.js': './local/plop', + 'c:\\local\\plop\\foo.js': 'c:/local/plop', + 'D:\\local\\plop\\foo.js': 'D:/local/plop', + 'D:\\local\\plop\\': 'D:/local/plop', + 'c:\\': 'c:', + 'c:': 'c:' + }; + for (var testCase in tests) { + test.assertEquals(fs.dirname(testCase), tests[testCase], 'fs.dirname() does its job for ' + testCase); + } + test.done(); +}); + +casper.test.begin('fs.isWindows() tests', 6, function(test) { + var tests = { + '/': false, + '/local/plop/foo.js': false, + 'D:\\local\\plop\\': true, + 'c:\\': true, + 'c:': true, + '\\\\Server\\Plop': true + }; + for (var testCase in tests) { + test.assertEquals(fs.isWindows(testCase), tests[testCase], 'fs.isWindows() does its job for ' + testCase); + } + test.done(); +}); diff --git a/vendor/casperjs/tests/suites/http_status.js b/vendor/casperjs/tests/suites/http_status.js new file mode 100755 index 0000000..a20947f --- /dev/null +++ b/vendor/casperjs/tests/suites/http_status.js @@ -0,0 +1,80 @@ +/*global casper*/ +/*jshint strict:false*/ +/** + * Special test server to test for HTTP status codes + * + */ +var fs = require('fs'); +var utils = require('utils'); + +casper.test.begin("HTTP status code handling", 163, { + setUp: function(test) { + this.server = require('webserver').create(); + this.server.listen(8090, function (request, response) { + response.statusCode = parseInt(/^\/(\d+)$/.exec(request.url)[1], 10); + response.write(""); + response.close(); + }); + var isGecko = (phantom.casperEngine === 'slimerjs'); + + this.testCodes = [ + 100, 101, 200, 201, 202, 203, 204, 205, 206, 207, 210, + 300, 301, 302, 303, 304, 305, 307, 310 + ]; + if (!isGecko) { + // it seems that the network layer of Gecko does not process these response + this.testCodes.push(102); + this.testCodes.push(118); + } + + if (utils.ltVersion(phantom.version, '1.9.0') || + utils.gteVersion(phantom.version, '1.9.2') || + isGecko) { + // https://github.com/ariya/phantomjs/issues/11163 + this.testCodes = this.testCodes.concat([ + 400, 401, 402, 403, 404, 405, 406, 407, 409, 410, 411, 412, 413, + 414, 415, 416, 417, 418, 422, 423, 424, 425, 426, 449, 450, + 500, 501, 502, 503, 504, 505, 507, 509 + ]); + if (!isGecko) { + // it seems that the network layer of Gecko has a different + // behavior for 408 than PhantomJS's webkit + this.testCodes.push(408); + } + } + if ((this.testCodes.length * 3) < 165 ) { + test.skip(163 - (this.testCodes.length * 3 - 2) ); + } + }, + + tearDown: function() { + this.server.close(); + }, + + test: function(test) { + casper.start(); + + // file protocol + casper.thenOpen('file://' + phantom.casperPath + '/tests/site/index.html', function() { + this.test.assertHttpStatus(null, 'file:// protocol does not set a HTTP status'); + }); + + casper.each(this.testCodes, function(self, code) { + if (code === 100) { + // HTTP 100 is CONTINUE, so don't expect a terminated response + return; + } + this.thenOpen('http://localhost:8090/' + code, function(resource) { + test.assertEquals(resource.status, code, + 'Status is stored in resource.status'); + test.assertEquals(this.currentHTTPStatus, code, + 'Status is stored in casper.currentHTTPStatus'); + test.assertHttpStatus(code, utils.format('HTTP %d handled' , code)); + }); + }); + + casper.run(function() { + this.test.done(); + }); + } +}); diff --git a/vendor/casperjs/tests/suites/pagestack.js b/vendor/casperjs/tests/suites/pagestack.js new file mode 100755 index 0000000..400bb65 --- /dev/null +++ b/vendor/casperjs/tests/suites/pagestack.js @@ -0,0 +1,33 @@ +/*global casper*/ +/*jshint strict:false, maxstatements:99*/ +var pagestack = require('pagestack'); +var utils = require('utils'); +var webpage = require('webpage'); + +casper.test.begin('pagestack module tests', 14, function(test) { + var stack = pagestack.create(); + var page1 = webpage.create(); + page1.url = 'page1.html'; + stack.push(page1); + test.assertEquals(stack.length, 1); + test.assert(utils.isWebPage(stack[0])); + test.assertEquals(stack[0], page1); + test.assertEquals(stack.list().length, 1); + test.assertEquals(stack.list()[0], page1.url); + + var page2 = webpage.create(); + page2.url = 'page2.html'; + stack.push(page2); + test.assertEquals(stack.length, 2); + test.assert(utils.isWebPage(stack[1])); + test.assertEquals(stack[1], page2); + test.assertEquals(stack.list().length, 2); + test.assertEquals(stack.list()[1], page2.url); + + test.assertEquals(stack.clean(page1), 1); + test.assertEquals(stack[0], page2); + test.assertEquals(stack.list().length, 1); + test.assertEquals(stack.list()[0], page2.url); + + test.done(); +}); diff --git a/vendor/casperjs/tests/suites/require.js b/vendor/casperjs/tests/suites/require.js new file mode 100755 index 0000000..62f7810 --- /dev/null +++ b/vendor/casperjs/tests/suites/require.js @@ -0,0 +1,37 @@ +/*global casper*/ +/*jshint strict:false*/ +var fs = require('fs'); +var modroot = fs.pathJoin(phantom.casperPath, 'tests', 'sample_modules'); + +casper.test.begin('Javascript module loading', 1, function(test) { + var jsmod; + try { + jsmod = require(fs.pathJoin(modroot, 'jsmodule')); + test.assertTrue(jsmod.ok, 'require() patched version can load a js module'); + } catch (e) { + test.fail('require() patched version can load a js module'); + } + test.done(); +}); + +casper.test.begin('CoffeeScript module loading', 1, function(test) { + var csmod; + try { + csmod = require(fs.pathJoin(modroot, 'csmodule')); + test.assertTrue(csmod.ok, 'require() patched version can load a coffeescript module'); + } catch (e) { + test.fail('require() patched version can load a coffeescript module'); + } + test.done(); +}); + +casper.test.begin('JSON module loading', 1, function(test) { + var config; + try { + config = require(fs.pathJoin(modroot, 'config.json')); + test.assertTrue(config.ok, 'require() patched version can load a json module'); + } catch (e) { + test.fail('require() patched version can load a json module'); + } + test.done(); +}); diff --git a/vendor/casperjs/tests/suites/tester/.casper b/vendor/casperjs/tests/suites/tester/.casper new file mode 100755 index 0000000..e69de29 diff --git a/vendor/casperjs/tests/suites/tester/assert.js b/vendor/casperjs/tests/suites/tester/assert.js new file mode 100755 index 0000000..3b87e40 --- /dev/null +++ b/vendor/casperjs/tests/suites/tester/assert.js @@ -0,0 +1,222 @@ +/*global casper*/ +/*jshint strict:false, maxstatements:99*/ +var fs = require('fs'); + +casper.test.begin('Common assertions tests', 46, function(test) { + casper.start('tests/site/index.html', function() { + test.assertTextExists('form', 'Tester.assertTextExists() checks that page body contains text'); + test.assertTextExist('form', 'Tester.assertTextExist() checks that page body contains text [alias]'); + test.assertTextDoesntExist('blah', "Tester.assertTextDoesntExist() checks that page body doesn't contain provided text"); + test.assertSelectorHasText('h1', 'Title', 'Tester.assertSelectorHasText() works as expected'); + test.assertSelectorDoesntHaveText('h1', 'Subtitle', 'Tester.assertSelectorDoesntHaveText() works as expected'); + test.assert(true, 'Tester.assert() works as expected'); + test.assertTrue(true, 'Tester.assertTrue() works as expected [alias]'); + test.assertTruthy('1', 'Tester.assertTruthy() works as expected'); + test.assertFalsy('', 'Tester.assertFalsy() works as expected'); + test.assertNot(false, 'Tester.assertNot() works as expected'); + test.assertEquals(true, true, 'Tester.assertEquals() works as expected'); + test.assertEqual(true, true, 'Tester.assertEqual() works as expected [alias]'); + test.assertNotEquals(true, false, 'Tester.assertNotEquals() works as expected'); + test.assertEval(function() { + return true; + }, 'Tester.assertEval() works as expected'); + test.assertEvaluate(function() { + return true; + }, 'Tester.assertEvaluate() works as expected [alias]'); + test.assertEvalEquals(function() { + return 42; + }, 42, 'Tester.assertEvalEquals() works as expected'); + test.assertEvalEqual(function() { + return 42; + }, 42, 'Tester.assertEvalEqual() works as expected [alias]'); + test.assertElementCount('ul', 1, 'Tester.assertElementCount() works as expected'); + test.assertElementCount('li', 3, 'Tester.assertElementCount() works as expected'); + test.assertElementCount('address', 0, 'Tester.assertElementCount() works as expected'); + test.assertExists('body', 'Tester.assertExists() works as expected'); + test.assertExist('body', 'Tester.assertExist() works as expected [alias]'); + test.assertFail(function() { + test.assert(false); + }, 'Tester.assertFail() tests for a failing assertion'); + test.assertSelectorExists('body', 'Tester.assertSelectorExists() works as expected [alias]'); + test.assertSelectorExist('body', 'Tester.assertSelectorExist() works as expected [alias]'); + test.assertDoesntExist('foobar', 'Tester.assertDoesntExist() works as expected'); + test.assertDoesntExist('foobar', 'Tester.assertNotExist() works as expected [alias]'); + // using file:// protocol, HTTP status is always null + test.assertHttpStatus(200, 'Tester.assertHttpStatus() works as expected'); + test.assertMatch("the lazy dog", /lazy/, 'Tester.assertMatch() works as expected'); + test.assertMatches("the lazy dog", /lazy/, 'Tester.assertMatches() works as expected [alias]'); + test.assertRaises(function() { + throw new Error('plop'); + }, [], 'Tester.assertRaises() works as expected'); + test.assertRaise(function() { + throw new Error('plop'); + }, [], 'Tester.assertRaise() works as expected [alias]'); + test.assertThrows(function() { + throw new Error('plop'); + }, [], 'Tester.assertThrows() works as expected [alias]'); + test.assertResourceExists(/index\.html/, 'Tester.assertResourceExists() works as expected'); + test.assertResourceExist(/index\.html/, 'Tester.assertResourceExist() works as expected [alias]'); + test.assertTitle('CasperJS test index', 'Tester.assertTitle() works as expected'); + test.assertTitleMatch(/test index/, 'Tester.assertTitleMatch() works as expected'); + test.assertTitleMatches(/test index/, 'Tester.assertTitleMatches() works as expected [alias]'); + test.assertType("plop", "string", "Tester.assertType() works as expected"); + test.assertInstanceOf("plop", String, "Tester.assertInstanceOf() works as expected"); + test.assertUrlMatch(/index\.html$/, "Tester.assertUrlMatch() works as expected"); + test.assertUrlMatches(/index\.html$/, "Tester.assertUrlMatches() works as expected [alias]"); + test.assertVisible('img', 'Tester.assertVisible() works as expected'); + test.assertNotVisible('p#hidden', 'Tester.assertNotVisible() works as expected'); + test.assertInvisible('p#hidden', 'Tester.assertInvisible() works as expected [alias]'); + }).run(function() { + test.done(); + }); +}); + +casper.test.begin('Tester.assertField(): filled inputs', 7, function(test) { + casper.start('tests/site/form.html', function() { + this.fill('form[action="result.html"]', { + 'email': '', + 'content': '', + 'check': false, + 'choice': '', + 'topic': '', + 'file': '', + 'checklist[]': [] + }); + test.assertField('email', '', 'Tester.assertField() works as expected with inputs'); + test.assertField('content', '', 'Tester.assertField() works as expected with textarea'); + test.assertField('check', false, 'Tester.assertField() works as expected with checkboxes'); + test.assertField('choice', null, 'Tester.assertField() works as expected with radios'); + test.assertField('topic', 'foo', 'Tester.assertField() works as expected with selects'); + test.assertField('file', '', 'Tester.assertField() works as expected with file inputs'); + test.assertField('checklist[]', [], 'Tester.assertField() works as expected with check lists'); + }).run(function() { + test.done(); + }); +}); + +casper.test.begin('Tester.assertField(): unfilled inputs', 7, function(test) { + var fpath = fs.pathJoin(phantom.casperPath, 'README.md'); + var fileValue = 'README.md'; + if (phantom.casperEngine === 'phantomjs') { + fileValue = 'C:\\fakepath\\README.md'; // phantomjs/webkit sets that; + } + + casper.start('tests/site/form.html', function() { + this.fill('form[action="result.html"]', { + 'email': 'chuck@norris.com', + 'content': 'Am watching thou', + 'check': true, + 'choice': 'no', + 'topic': 'bar', + 'file': fpath, + 'checklist[]': ['1', '3'] + }); + test.assertField('email', 'chuck@norris.com', 'Tester.assertField() works as expected with inputs'); + test.assertField('content', 'Am watching thou', 'Tester.assertField() works as expected with textarea'); + test.assertField('check', true, 'Tester.assertField() works as expected with checkboxes'); + test.assertField('choice', 'no', 'Tester.assertField() works as expected with radios'); + test.assertField('topic', 'bar', 'Tester.assertField() works as expected with selects'); + test.assertField('file', fileValue, + 'Tester.assertField() works as expected with file inputs'); + test.assertField('checklist[]', ['1', '3'], 'Tester.assertField() works as expected with check lists'); + }).run(function() { + test.done(); + }); +}); + +casper.test.begin('Tester.assertField(): nonexistent fields', 2, function(test) { + casper.start('tests/site/form.html', function() { + test.assertFail(function() { + test.assertField('nonexistent', ''); + }, 'Tester.assertField() only checks for existing fields'); + }).run(function() { + test.done(); + }); +}); + +casper.test.begin('Tester.assertField(): CSS selectors', 1, function(test) { + casper.start('tests/site/form.html', function() { + this.fill('form[action="result.html"]', { + 'email': 'albert@camus.com' + }); + + test.assertField({ + type: 'css', + path: '#email' + }, + 'albert@camus.com', + 'Tester.assertField() works as expected with CSS selectors' + ); + }).run(function() { + test.done(); + }); +}); + +casper.test.begin('Tester.assertField(): XPath selectors', 1, function(test) { + casper.start('tests/site/form.html', function() { + this.fill('form[action="result.html"]', { + 'email': 'albert@camus.com' + }); + + test.assertField({ + type: 'xpath', + path: '/html/body/form[1]/input[1]' + }, + 'albert@camus.com', + 'Tester.assertField() works as expected with XPath selectors' + ); + }).run(function() { + test.done(); + }); +}); + +casper.test.begin('Tester.assertField(): invalid selectors', 1, function(test) { + casper.start('tests/site/form.html', function() { + this.fill('form[action="result.html"]', { + 'email': 'albert@camus.com' + }); + + test.assertRaise(function() { + test.assertField({ + type: 'albert' + }, + 'albert@camus.com', + 'Tester.assertField() works as expected with XPath selectors' + ); + }, [], 'should throw an error for an invalid selector'); + }).run(function() { + test.done(); + }); +}); + +casper.test.begin('Tester.assertFieldCSS(): CSS selectors', 1, function(test) { + casper.start('tests/site/form.html', function() { + this.fill('form[action="result.html"]', { + 'email': 'albert@camus.com' + }); + + test.assertFieldCSS( + '#email', + 'albert@camus.com', + 'Tester.assertFieldCSS() works as expected with CSS selectors' + ); + }).run(function() { + test.done(); + }); +}); + +casper.test.begin('Tester.assertFieldXPath(): XPath selectors', 1, function(test) { + casper.start('tests/site/form.html', function() { + this.fill('form[action="result.html"]', { + 'email': 'albert@camus.com' + }); + + test.assertFieldXPath( + '/html/body/form[1]/input[1]', + 'albert@camus.com', + 'Tester.assertFieldXPath() works as expected with XPath selectors' + ); + }).run(function() { + test.done(); + }); +}); diff --git a/vendor/casperjs/tests/suites/tester/begin-config.js b/vendor/casperjs/tests/suites/tester/begin-config.js new file mode 100755 index 0000000..67e1165 --- /dev/null +++ b/vendor/casperjs/tests/suites/tester/begin-config.js @@ -0,0 +1,35 @@ +/*jshint strict:false, eqeqeq:false*/ +/*global CasperError, casper, console, phantom, require*/ +var steps = []; + +casper.test.begin('Tester.begin() configuration', 10, { + fixtures: [1, 2, 3], + + _this: function() { + return this; + }, + + setUp: function(test) { + steps.push('setUp'); + test.pass('config.setUp() has been called'); + test.assert(this == this._this(), 'config.setUp() is using the expected context'); + test.assertEquals(this.fixtures, [1, 2, 3], 'config.setUp() accesses fixtures'); + }, + + tearDown: function(test) { + steps.push('tearDown'); + test.pass('config.tearDown() has been called'); + test.assert(this == this._this(), 'config.test() is using the expected context'); + test.assertEquals(this.fixtures, [1, 2, 3], 'config.tearDown() accesses fixtures'); + test.assertEquals(steps, ['setUp', 'test', 'tearDown'], + 'Tester.begin() has processed the configuration in the expected order'); + }, + + test: function(test) { + steps.push('test'); + test.pass('config.test() has been called'); + test.assert(this == this._this(), 'config.tearDown() is using the expected context'); + test.assertEquals(this.fixtures, [1, 2, 3], 'config.test() accesses fixtures'); + test.done(); + } +}); diff --git a/vendor/casperjs/tests/suites/tester/setup-teardown-async.js b/vendor/casperjs/tests/suites/tester/setup-teardown-async.js new file mode 100755 index 0000000..6b65b23 --- /dev/null +++ b/vendor/casperjs/tests/suites/tester/setup-teardown-async.js @@ -0,0 +1,31 @@ +/*global casper*/ +/*jshint strict:false*/ + +var setUp, tearDown; + +casper.test.setUp(function(done) { + setTimeout(function() { + setUp = true; + done(); + }, 50); +}); + +casper.test.tearDown(function(done) { + setTimeout(function() { + tearDown = true; + done(); + // reset + casper.test.setUp(); + casper.test.tearDown(); + }, 50); +}); + +casper.test.begin('setUp() tests', 1, function(test) { + test.assertTrue(setUp, 'Tester.setUp() executed the async setup function'); + test.done(); +}); + +casper.test.begin('tearDown() tests', 1, function(test) { + test.assertTrue(tearDown, 'Tester.tearDown() executed the async tear down function'); + test.done(); +}); diff --git a/vendor/casperjs/tests/suites/tester/setup-teardown.js b/vendor/casperjs/tests/suites/tester/setup-teardown.js new file mode 100755 index 0000000..60ceba3 --- /dev/null +++ b/vendor/casperjs/tests/suites/tester/setup-teardown.js @@ -0,0 +1,25 @@ +/*global casper*/ +/*jshint strict:false*/ + +var setUp, tearDown; + +casper.test.setUp(function() { + setUp = true; +}); + +casper.test.tearDown(function() { + tearDown = true; + // reset + casper.test.setUp(); + casper.test.tearDown(); +}); + +casper.test.begin('setUp() tests', 1, function(test) { + test.assertTrue(setUp, 'Tester.setUp() executed the setup function'); + test.done(); +}); + +casper.test.begin('tearDown() tests', 1, function(test) { + test.assertTrue(tearDown, 'Tester.tearDown() executed the tear down function'); + test.done(); +}); diff --git a/vendor/casperjs/tests/suites/tester/skip.js b/vendor/casperjs/tests/suites/tester/skip.js new file mode 100755 index 0000000..361294b --- /dev/null +++ b/vendor/casperjs/tests/suites/tester/skip.js @@ -0,0 +1,23 @@ +/*global casper*/ +/*jshint strict:false*/ +casper.test.begin('Skip tests', 4, function(test) { + test.assert(true, 'First test executed'); + test.assert(true, 'Second test executed'); + test.skip(2, 'Two tests skipped'); + test.done(); +}); + +casper.test.begin('Skip tests after', 4, function(test) { + test.skip(2, 'Two tests skipped'); + test.assert(true, 'Third test executed'); + test.assert(true, 'Fourth test executed'); + test.done(); +}); + +casper.test.begin('Skip tests (asynchronous)', 1, function(test) { + casper.start('tests/site/index.html', function() { + test.skip(1); + }).run(function() { + test.done(); + }); +}); diff --git a/vendor/casperjs/tests/suites/tester/test-order.js b/vendor/casperjs/tests/suites/tester/test-order.js new file mode 100755 index 0000000..aad399c --- /dev/null +++ b/vendor/casperjs/tests/suites/tester/test-order.js @@ -0,0 +1,21 @@ +/*jshint strict:false*/ +/*global CasperError, casper, console, phantom, require*/ +var fs = require('fs'); + +casper.test.begin('Tester.sortFiles()', 1, function suite(test) { + var testDirRoot = fs.pathJoin(phantom.casperPath, 'tests', 'testdir'); + var files = test.findTestFiles(testDirRoot); + var expected = [ + "01_a/abc.js", + "01_a/def.js", + "02_b/abc.js", + "03_a.js", + "03_b.js", + "04/01_init.js", + "04/02_do.js" + ].map(function(entry) { + return fs.pathJoin.apply(fs, [testDirRoot].concat(entry.split('/'))); + }); + test.assertEquals(files, expected, 'findTestFiles() find test files and sort them'); + test.done(); +}); diff --git a/vendor/casperjs/tests/suites/tester/testcase.js b/vendor/casperjs/tests/suites/tester/testcase.js new file mode 100755 index 0000000..3a7bd3e --- /dev/null +++ b/vendor/casperjs/tests/suites/tester/testcase.js @@ -0,0 +1,50 @@ +/*jshint strict:false, maxstatements:99, maxcomplexity:99*/ +/*global CasperError, casper, console, phantom, require*/ + +var TestCaseResult = require('tester').TestCaseResult; + +casper.test.begin('TestCaseResult.constructor() tests', 4, function(test) { + var caseResult1 = new TestCaseResult(); + test.assertType(caseResult1.name, "undefined", 'TestCaseResult.constructor() name is undefined by default'); + test.assertType(caseResult1.file, "undefined", 'TestCaseResult.constructor() file is undefined by default'); + var caseResult2 = new TestCaseResult({name: 'foo', file: '/tmp/foo'}); + test.assertEquals(caseResult2.name, "foo", 'TestCaseResult.constructor() can set name'); + test.assertEquals(caseResult2.file, "/tmp/foo", 'TestCaseResult.constructor() can set file'); + test.done(); +}); + +casper.test.begin('TestCaseResult.addSuccess() and TestCaseResult.addFailure() tests', 22, function(test) { + var caseResult = new TestCaseResult({name: 'foo', file: '/tmp/foo'}); + test.assertEquals(caseResult.assertions, 0, 'test case result counts no assertion by default'); + test.assertEquals(caseResult.passed, 0, 'test case result counts no success by default'); + test.assertEquals(caseResult.failed, 0, 'test case result counts no failure by default'); + test.assertEquals(caseResult.calculateDuration(), 0, + 'TestCaseResult.calculateDuration() computes initial tests duration'); + var success = {}; + caseResult.addSuccess(success, 1337); + test.assertEquals(caseResult.assertions, 1, 'test case result counts one assertion'); + test.assertEquals(caseResult.passed, 1, 'test case result counts one success'); + test.assertEquals(caseResult.failed, 0, 'test case result counts no failure'); + test.assertEquals(caseResult.passes[0], success, 'TestCaseResult.addSuccess() added a success to the stack'); + test.assertEquals(caseResult.passes[0].time, 1337, 'TestCaseResult.addSuccess() added test duration'); + test.assertEquals(caseResult.passes[0].suite, 'foo', 'TestCaseResult.addSuccess() added suite name'); + test.assertEquals(caseResult.calculateDuration(), 1337, + 'TestCaseResult.calculateDuration() computes tests duration'); + var failure = {}; + caseResult.addFailure(failure, 42); + test.assertEquals(caseResult.assertions, 2, 'test case result counts two assertions'); + test.assertEquals(caseResult.passed, 1, 'test case result counts one success'); + test.assertEquals(caseResult.failed, 1, 'test case result counts no failure'); + test.assertEquals(caseResult.failures[0], failure, 'TestCaseResult.addFailure() added a failure to the stack'); + test.assertEquals(caseResult.failures[0].time, 42, 'TestCaseResult.addFailure() added test duration'); + test.assertEquals(caseResult.failures[0].suite, 'foo', 'TestCaseResult.addFailure() added suite name'); + test.assertEquals(caseResult.calculateDuration(), 1337 + 42, + 'TestCaseResult.calculateDuration() computes new tests duration'); + caseResult.addSuccess({}, 1000); + test.assertEquals(caseResult.assertions, 3, 'test case result counts three assertions'); + test.assertEquals(caseResult.passed, 2, 'test case result counts two successes'); + test.assertEquals(caseResult.failed, 1, 'test case result counts one failure'); + test.assertEquals(caseResult.calculateDuration(), 1337 + 42 + 1000, + 'TestCaseResult.calculateDuration() computes new tests duration'); + test.done(); +}); diff --git a/vendor/casperjs/tests/suites/tester/testsuite.js b/vendor/casperjs/tests/suites/tester/testsuite.js new file mode 100755 index 0000000..ac2057b --- /dev/null +++ b/vendor/casperjs/tests/suites/tester/testsuite.js @@ -0,0 +1,56 @@ +/*jshint strict:false*/ +/*global CasperError, casper, console, phantom, require*/ + +var TestCaseResult = require('tester').TestCaseResult, + TestSuiteResult = require('tester').TestSuiteResult; + +function generateCaseResult(options) { + var i, + nPasses = options && ~~options.nPasses, + nFailures = options && ~~options.nFailures, + caseResult = new TestCaseResult(options); + for (i = 0; i < nFailures; i++) { + caseResult.addFailure({}, i * 1000); + } + for (i = 0; i < nPasses; i++) { + caseResult.addSuccess({}, i * 1000); + } + return caseResult; +} + +casper.test.begin('TestSuiteResult() basic tests', 8, function(test) { + var suiteResult = new TestSuiteResult(); + test.assertEquals(suiteResult.constructor.name, 'Array', 'TestSuiteResult() is derived from Array'); + test.assertEquals(suiteResult.countTotal(), 0); + test.assertEquals(suiteResult.countFailed(), 0); + test.assertEquals(suiteResult.countPassed(), 0); + test.assertEquals(suiteResult.getAllFailures(), []); + test.assertEquals(suiteResult.getAllPasses(), []); + test.assertEquals(suiteResult.getAllResults(), []); + test.assertEquals(suiteResult.calculateDuration(), 0); + test.done(); +}); + +casper.test.begin('TestSuiteResult() accumulation tests', 7, function(test) { + var suiteResult = new TestSuiteResult(); + suiteResult.push(generateCaseResult({ + name: 'foo', + file: '/tmp/foo', + nPasses: 4, + nFailures: 1 + })); + suiteResult.push(generateCaseResult({ + name: 'bar', + file: '/tmp/bar', + nPasses: 3, + nFailures: 0 + })); + test.assertEquals(suiteResult.countTotal(), 8); + test.assertEquals(suiteResult.countFailed(), 1); + test.assertEquals(suiteResult.countPassed(), 7); + test.assertEquals(suiteResult.getAllFailures().length, 1); + test.assertEquals(suiteResult.getAllPasses().length, 7); + test.assertEquals(suiteResult.getAllResults().length, 8); + test.assertEquals(suiteResult.calculateDuration(), 9000); + test.done(); +}); diff --git a/vendor/casperjs/tests/suites/utils.js b/vendor/casperjs/tests/suites/utils.js new file mode 100755 index 0000000..3fdb754 --- /dev/null +++ b/vendor/casperjs/tests/suites/utils.js @@ -0,0 +1,485 @@ +/*global casper*/ +/*jshint strict:false, maxstatements:99*/ +var utils = require('utils'), + t = casper.test, + x = require('casper').selectXPath; + +casper.test.begin('utils.betterTypeOf() tests', 10, function(test) { + var testCases = [ + {subject: 1, expected: 'number'}, + {subject: '1', expected: 'string'}, + {subject: {}, expected: 'object'}, + {subject: [], expected: 'array'}, + {subject: undefined, expected: 'undefined'}, + {subject: null, expected: 'null'}, + {subject: function(){}, expected: 'function'}, + {subject: window, expected: 'domwindow'}, + {subject: new Date(), expected: 'date'}, + {subject: new RegExp(), expected: 'regexp'} + ]; + testCases.forEach(function(testCase) { + test.assertEquals(utils.betterTypeOf(testCase.subject), testCase.expected, + utils.format('betterTypeOf() detects expected type "%s"', testCase.expected)); + }); + test.done(); +}); + +casper.test.begin('utils.betterInstanceOf() tests', 13, function(test) { + /*global XMLDocument*/ + // need two objects to test inheritance + function Cow(){} var daisy = new Cow(); + function SuperCow(){} SuperCow.prototype = new Cow(); var superDaisy = new SuperCow(); + var date = new Date(); var regex = new RegExp(); var xmlDoc = document.implementation.createDocument("<y>", "x", null); + var testCases = [ + {subject: 1, fn: Number, expected: true}, + {subject: '1', fn: String, expected: true}, + {subject: {}, fn: Object, expected: true}, + {subject: [], fn: Array, expected: true}, + {subject: undefined, fn: Array, expected: false}, + {subject: null, fn: Array, expected: false}, + {subject: function(){}, fn: Function, expected: true}, + {subject: date, fn: Date, expected: true}, + {subject: regex, fn: RegExp, expected: true}, + {subject: xmlDoc, fn: XMLDocument, expected: true}, + {subject: daisy, fn: Cow, expected: true}, + {subject: superDaisy, fn: SuperCow, expected: true}, + {subject: superDaisy, fn: Cow, expected: true} + ]; + testCases.forEach(function(testCase) { + test.assertEquals(utils.betterInstanceOf(testCase.subject, testCase.fn), testCase.expected, + utils.format('betterInstanceOf() detects expected constructor "%s"', testCase.fn.name)); + }); + test.done(); +}); + +casper.test.begin('utils.cleanUrl() tests', 11, function(test) { + var testCases = { + 'http://google.com/': 'http://google.com/', + 'http://google.com': 'http://google.com/', + 'http://www.google.com/': 'http://www.google.com/', + 'http://www.google.com/?plop=2': 'http://www.google.com/?plop=2', + 'https://google.com/': 'https://google.com/', + 'https://google.com': 'https://google.com/', + 'https://www.google.com/': 'https://www.google.com/', + 'https://www.google.com/?plop=2': 'https://www.google.com/?plop=2', + 'https://www.google.com?plop=2': 'https://www.google.com/?plop=2', + 'file:///Users/toto/toto.html': 'file:///Users/toto/toto.html', + '/100': '/100' + }; + for (var testCase in testCases) { + test.assertEquals(utils.cleanUrl(testCase), testCases[testCase], 'cleanUrl() cleans an URL'); + } + test.done(); +}); + +casper.test.begin('utils.clone() tests', 2, function(test) { + var a = {a: 1, b: 2, c: [1, 2]}; + test.assertEquals(utils.clone(a), a); + var b = [1, 2, 3, a]; + test.assertEquals(utils.clone(b), b); + test.done(); +}); + +if (utils.gteVersion(phantom.version, '1.9.0')) { + casper.test.begin('utils.computeModifier() tests', 7, function(test) { + var modifiers = require('webpage').create().event.modifier; + test.assertType(modifiers, "object"); + test.assertEquals(utils.computeModifier("", modifiers), 0, + 'computeModifier() computes a "none" modifier'); + test.assertEquals(utils.computeModifier("alt", modifiers), + modifiers.alt, + 'computeModifier() computes an "alt" modifier'); + test.assertEquals(utils.computeModifier("ctrl+alt", modifiers), + modifiers.ctrl | modifiers.alt, + 'computeModifier() computes a "ctrl+alt" modifier'); + test.assertEquals(utils.computeModifier("ctrl+alt+shift", modifiers), + modifiers.ctrl | modifiers.alt | modifiers.shift, + 'computeModifier() computes a "ctrl+alt+shift" modifier'); + test.assertThrows(utils.computeModifier, ["chucknorris", modifiers], + 'computeModifier() checks for a valid modifier'); + test.assertThrows(utils.computeModifier, ["chuck+norris", modifiers], + 'computeModifier() checks for a valid complex modifier'); + test.done(); + }); +} + +casper.test.begin('decodeUrl() tests', 4, function(test) { + /* global escape */ + test.assertEquals(utils.decodeUrl('foo'), 'foo'); + test.assertEquals(utils.decodeUrl('Forlì'), 'Forlì'); + test.assertEquals(utils.decodeUrl(encodeURIComponent('Forlì')), 'Forlì'); + test.assertEquals(utils.decodeUrl(escape('Forlì')), 'Forlì'); + test.done(); +}); + +casper.test.begin('equals() tests', 23, function(test) { + test.assert(utils.equals(null, null), 'equals() null equality'); + test.assertNot(utils.equals(null, undefined), 'equals() null vs. undefined inequality'); + test.assert(utils.equals("hi", "hi"), 'equals() string equality'); + test.assertNot(utils.equals("hi", "ih"), 'equals() string inequality'); + test.assert(utils.equals(5, 5), 'equals() number equality'); + test.assertNot(utils.equals("5", 5), 'equals() number equality without implicit cast'); + test.assert(utils.equals(5, 5.0), 'equals() number equality with cast'); + test.assertNot(utils.equals(5, 10), 'equals() number inequality'); + test.assert(utils.equals([], []), 'equals() empty array equality'); + test.assert(utils.equals([1,2], [1,2]), 'equals() array equality'); + test.assert(utils.equals([1,2,[1,2,function(){}]], [1,2,[1,2,function(){}]]), + 'equals() complex array equality'); + test.assertNot(utils.equals([1,2,[1,2,function(a){}]], [1,2,[1,2,function(b){}]]), + 'equals() complex array inequality'); + test.assertNot(utils.equals([1,2], [2,1]), 'equals() shuffled array inequality'); + test.assertNot(utils.equals([1,2], [1,2,3]), 'equals() array length inequality'); + test.assert(utils.equals({}, {}), 'equals() empty object equality'); + test.assert(utils.equals({a:1,b:2}, {a:1,b:2}), 'equals() object length equality'); + test.assert(utils.equals({a:1,b:2}, {b:2,a:1}), 'equals() shuffled object keys equality'); + test.assertNot(utils.equals({a:1,b:2}, {a:1,b:3}), 'equals() object inequality'); + test.assert(utils.equals({1:{name:"bob",age:28}, 2:{name:"john",age:26}}, + {1:{name:"bob",age:28}, 2:{name:"john",age:26}}), + 'equals() complex object equality'); + test.assertNot(utils.equals({1:{name:"bob",age:28}, 2:{name:"john",age:26}}, + {1:{name:"bob",age:28}, 2:{name:"john",age:27}}), + 'equals() complex object inequality'); + test.assert(utils.equals(function(x){return x;}, function(x){return x;}), + 'equals() function equality'); + test.assertNot(utils.equals(function(x){return x;}, function(y){return y+2;}), + 'equals() function inequality'); + test.assert(utils.equals([{a:1, b:2}, {c:3, d:4}], [{a:1, b:2}, {c:3, d:4}]), + 'equals() arrays of objects'); + test.done(); +}); + +casper.test.begin('fileExt() tests', 6, function(test) { + var testCases = { + 'foo.ext': 'ext', + 'FOO.EXT': 'ext', + 'a.ext': 'ext', + '.ext': 'ext', + 'toto.': '', + ' plop.ext ': 'ext' + }; + for (var testCase in testCases) { + test.assertEquals(utils.fileExt(testCase), testCases[testCase], + 'fileExt() extract file extension'); + } + test.done(); +}); + +casper.test.begin('fillBlanks() tests', 3, function(test) { + var testCases = { + 'foo': 'foo ', + ' foo bar ': ' foo bar ', + ' foo bar ': ' foo bar ' + }; + for (var testCase in testCases) { + test.assertEquals(utils.fillBlanks(testCase, 10), testCases[testCase], + 'fillBlanks() fills blanks'); + } + test.done(); +}); + +casper.test.begin('getPropertyPath() tests', 7, function(test) { + var testCases = [ + { + input: utils.getPropertyPath({}, 'a.b.c'), + output: undefined + }, + { + input: utils.getPropertyPath([1, 2, 3], 'a.b.c'), + output: undefined + }, + { + input: utils.getPropertyPath({ a: { b: { c: 1 } }, c: 2 }, 'a.b.c'), + output: 1 + }, + { + input: utils.getPropertyPath({ a: { b: { c: 1 } }, c: 2 }, 'a.b.x'), + output: undefined + }, + { + input: utils.getPropertyPath({ a: { b: { c: 1 } }, c: 2 }, 'a.b'), + output: { c: 1 } + }, + { + input: utils.getPropertyPath({ 'a-b': { 'c-d': 1} }, 'a-b.c-d'), + output: 1 + }, + { + input: utils.getPropertyPath({ 'a.b': { 'c.d': 1} }, 'a.b.c.d'), + output: undefined + } + ]; + testCases.forEach(function(testCase) { + test.assertEquals(testCase.input, testCase.output, + 'getPropertyPath() gets a property using a path'); + }); + test.done(); +}); + +casper.test.begin('isArray() tests', 3, function(test) { + test.assertEquals(utils.isArray([]), true, 'isArray() checks for an Array'); + test.assertEquals(utils.isArray({}), false, 'isArray() checks for an Array'); + test.assertEquals(utils.isArray("foo"), false, 'isArray() checks for an Array'); + test.done(); +}); + +casper.test.begin('isClipRect() tests', 5, function(test) { + var testCases = [ + [{}, false], + [{top: 2}, false], + [{top: 2, left: 2, width: 2, height: 2}, true], + [{top: 2, left: 2, height: 2, width: 2}, true], + [{top: 2, left: 2, width: 2, height: new Date()}, false] + ]; + testCases.forEach(function(testCase) { + test.assertEquals(utils.isClipRect(testCase[0]), testCase[1], + 'isClipRect() checks for a ClipRect'); + }); + test.done(); +}); + +casper.test.begin('isHTTPResource() tests', 6, function(test) { + var testCases = [ + [{}, false], + [{url: 'file:///var/www/i.html'}, false], + [{url: 'mailto:plop@plop.com'}, false], + [{url: 'ftp://ftp.plop.com'}, false], + [{url: 'HTTP://plop.com/'}, true], + [{url: 'https://plop.com/'}, true] + ]; + testCases.forEach(function(testCase) { + test.assertEquals(utils.isHTTPResource(testCase[0]), testCase[1], + 'isHTTPResource() checks for an HTTP resource'); + }); + test.done(); +}); + +casper.test.begin('isObject() tests', 8, function(test) { + test.assertEquals(utils.isObject({}), true, 'isObject() checks for an Object'); + test.assertEquals(utils.isObject([]), true, 'isObject() checks for an Object'); + test.assertEquals(utils.isObject(1), false, 'isObject() checks for an Object'); + test.assertEquals(utils.isObject("1"), false, 'isObject() checks for an Object'); + test.assertEquals(utils.isObject(function(){}), false, 'isObject() checks for an Object'); + test.assertEquals(utils.isObject(new Function('return {};')()), true, 'isObject() checks for an Object'); + test.assertEquals(utils.isObject(require('webpage').create()), true, 'isObject() checks for an Object'); + test.assertEquals(utils.isObject(null), false, 'isObject() checks for an Object'); + test.done(); +}); + +casper.test.begin('isValidSelector() tests', 10, function(test) { + t.assertEquals(utils.isValidSelector({}), false, + 'isValidSelector() checks for a valid selector'); + t.assertEquals(utils.isValidSelector(""), false, + 'isValidSelector() checks for a valid selector'); + t.assertEquals(utils.isValidSelector("a"), true, + 'isValidSelector() checks for a valid selector'); + t.assert( + utils.isValidSelector('div#plop form[name="form"] input[type="submit"]'), + 'isValidSelector() checks for a valid selector' + ); + t.assertEquals(utils.isValidSelector(x('//a')), true, + 'isValidSelector() checks for a valid selector'); + t.assertEquals(utils.isValidSelector({ + type: "css", + path: 'div#plop form[name="form"] input[type="submit"]' + }), true, 'isValidSelector() checks for a valid selector'); + t.assertEquals(utils.isValidSelector({ + type: "xpath", + path: '//a' + }), true, 'isValidSelector() checks for a valid selector'); + t.assertEquals(utils.isValidSelector({ + type: "css" + }), false, 'isValidSelector() checks for a valid selector'); + t.assertEquals(utils.isValidSelector({ + type: "xpath" + }), false, 'isValidSelector() checks for a valid selector'); + t.assertEquals(utils.isValidSelector({ + type: "css3", + path: "a" + }), false, 'isValidSelector() checks for a valid selector'); + test.done(); +}); + +casper.test.begin('isWebPage() tests', 3, function(test) { + var pageModule = require('webpage'); + test.assertEquals(utils.isWebPage(pageModule), false, + 'isWebPage() checks for a WebPage instance'); + test.assertEquals(utils.isWebPage(pageModule.create()), true, + 'isWebPage() checks for a WebPage instance'); + test.assertEquals(utils.isWebPage(null), false, + 'isWebPage() checks for a WebPage instance'); + test.done(); +}); + +casper.test.begin('isJsFile() tests', 5, function(test) { + var testCases = { + '': false, + 'toto.png': false, + 'plop': false, + 'gniii.coffee': true, + 'script.js': true + }; + for (var testCase in testCases) { + test.assertEquals(utils.isJsFile(testCase), testCases[testCase], + 'isJsFile() checks for js file'); + } + test.done(); +}); + + +casper.test.begin('mergeObjects() tests', 10, function(test) { + /* jshint eqeqeq:false */ + var testCases = [ + { + obj1: {a: 1}, obj2: {b: 2}, merged: {a: 1, b: 2} + }, + { + obj1: {}, obj2: {a: 1}, merged: {a: 1} + }, + { + obj1: {}, obj2: {a: {b: 2}}, merged: {a: {b: 2}} + }, + { + obj1: {a: 1}, obj2: {}, merged: {a: 1} + }, + { + obj1: {a: 1}, obj2: {a: 2}, merged: {a: 2} + }, + { + obj1: {x: 0, double: function(){return this.x*2;}}, + obj2: {triple: function(){return this.x*3;}}, + merged: { + x: 0, + double: function(){return this.x*2;}, + triple: function(){return this.x*3;} + } + } + ]; + testCases.forEach(function(testCase) { + test.assertEquals( + utils.mergeObjects(testCase.obj1, testCase.obj2), + testCase.merged, + 'mergeObjects() can merge objects' + ); + }); + var obj = {x: 1}, + qtruntimeobject = {foo: 'baz'}; + + var merged1 = utils.mergeObjects({}, {a: obj}); + merged1.a.x = 2; + test.assertEquals(obj.x, 1, 'mergeObjects() creates deep clones #1'); + + var merged2 = utils.mergeObjects({a: {}}, {a: obj}); + merged2.a.x = 2; + test.assertEquals(obj.x, 1, 'mergeObjects() creates deep clones #2'); + + var refObj = {a: qtruntimeobject}; + var merged3 = utils.mergeObjects({}, refObj, {keepReferences: false}); + test.assertFalsy(merged3.a == refObj.a, 'disabling references should not point to same object'); + + var merged4 = utils.mergeObjects({}, refObj, {keepReferences: true}); + test.assert(merged4.a == refObj.a, 'enabling references should point to same object'); + + test.done(); +}); + +casper.test.begin('objectValues() tests', 2, function(test) { + test.assertEquals(utils.objectValues({}), [], + 'objectValues() can extract object values'); + test.assertEquals(utils.objectValues({a: 1, b: 2}), [1, 2], + 'objectValues() can extract object values'); + test.done(); +}); + +casper.test.begin('quoteXPathAttributeString() tests', 2, function(test) { + casper.start('tests/site/click.html', function() { + var selector = utils.format('//a[text()=%s]', + utils.quoteXPathAttributeString('Label with double "quotes"')); + test.assertExists(x(selector), utils.format('Xpath selector "%s" is found on "tests/site/click.html" page', selector)); + selector = utils.format('//a[text()=%s]', + utils.quoteXPathAttributeString("Label with single 'quotes'")); + test.assertExists(x(selector), utils.format('Xpath selector "%s" is found on "tests/site/click.html" page', selector)); + }).run(function() { + test.done(); + }); +}); + +casper.test.begin('unique() tests', 4, function(test) { + var testCases = [ + { + input: [1,2,3], + output: [1,2,3] + }, + { + input: [1,2,3,2,1], + output: [1,2,3] + }, + { + input: ["foo", "bar", "foo"], + output: ["foo", "bar"] + }, + { + input: [], + output: [] + } + ]; + testCases.forEach(function(testCase) { + test.assertEquals(utils.unique(testCase.input), testCase.output, + 'unique() computes unique values of an array'); + }); + test.done(); +}); + +casper.test.begin('cmpVersion() tests', 10, function suite(test) { + test.assertEquals(utils.cmpVersion('1.0.0', '2.0.0'), -1, + 'cmpVersion() can compare version strings'); + test.assertEquals(utils.cmpVersion('1.0.0-DEV', '2.0.0-BOOM'), -1, + 'cmpVersion() can compare version strings'); + test.assertEquals(utils.cmpVersion('1.0.0', '1.1.0'), -1, + 'cmpVersion() can compare version strings'); + test.assertEquals(utils.cmpVersion('1.1.0', '1.0.0'), 1, + 'cmpVersion() can compare version strings'); + test.assertEquals(utils.cmpVersion('0.0.3', '0.0.4'), -1, + 'cmpVersion() can compare version strings'); + test.assertEquals(utils.cmpVersion('0.0.3', '1.0.3'), -1, + 'cmpVersion() can compare version strings'); + test.assertEquals(utils.cmpVersion('0.1', '1.0.3.8'), -1, + 'cmpVersion() can compare version strings'); + test.assertEquals(utils.cmpVersion({major: 1, minor: 2, patch: 3}, + {major: 1, minor: 2, patch: 4}), -1, + 'cmpVersion() can compare version objects'); + test.assertEquals(utils.cmpVersion({major: 2, minor: 0, patch: 3}, + {major: 1, minor: 0, patch: 4}), 1, + 'cmpVersion() can compare version objects'); + test.assertEquals(utils.cmpVersion({major: 0, minor: 0, patch: 3}, + {major: 1, minor: 0, patch: 3}), -1, + 'cmpVersion() can compare version objects'); + test.done(); +}); + +casper.test.begin('gteVersion() tests', 4, function suite(test) { + test.assert(utils.gteVersion('1.1.0', '1.0.0'), + 'gteVersion() checks for a greater or equal version'); + test.assertNot(utils.gteVersion('1.0.0', '1.1.0'), + 'gteVersion() checks for a greater or equal version'); + test.assert(utils.gteVersion({major: 1, minor: 1, patch: 0}, + {major: 1, minor: 0, patch: 0}), + 'gteVersion() checks for a greater or equal version'); + test.assertNot(utils.gteVersion({major: 1, minor: 0, patch: 0}, + {major: 1, minor: 1, patch: 0}), + 'gteVersion() checks for a greater or equal version'); + test.done(); +}); + +casper.test.begin('ltVersion() tests', 4, function suite(test) { + test.assert(utils.ltVersion('1.0.0', '1.1.0'), + 'ltVersion() checks for a lesser version'); + test.assertNot(utils.ltVersion('1.1.0', '1.0.0'), + 'ltVersion() checks for a lesser version'); + test.assert(utils.ltVersion({major: 1, minor: 0, patch: 0}, + {major: 1, minor: 1, patch: 0}), + 'ltVersion() checks for a lesser version'); + test.assertNot(utils.ltVersion({major: 1, minor: 1, patch: 0}, + {major: 1, minor: 0, patch: 0}), + 'ltVersion() checks for a lesser version'); + test.done(); +}); diff --git a/vendor/casperjs/tests/suites/xunit.js b/vendor/casperjs/tests/suites/xunit.js new file mode 100755 index 0000000..57077b7 --- /dev/null +++ b/vendor/casperjs/tests/suites/xunit.js @@ -0,0 +1,77 @@ +/*global casper, __utils__*/ +/*jshint strict:false*/ +var tester = require('tester'); +var testpage = require('webpage').create(); + +casper.test.begin('XUnitReporter() initialization', 1, function suite(test) { + var xunit = require('xunit').create(); + var results = new tester.TestSuiteResult(); + xunit.setResults(results); + test.assertTruthy(xunit.getXML()); + test.done(); +}); + +casper.test.begin('XUnitReporter() can hold test suites', 4, function suite(test) { + var xunit = require('xunit').create(); + var results = new tester.TestSuiteResult(); + var suite1 = new tester.TestCaseResult({ + name: 'foo', + file: '/foo' + }); + results.push(suite1); + var suite2 = new tester.TestCaseResult({ + name: 'bar', + file: '/bar' + }); + results.push(suite2); + xunit.setResults(results); + casper.start().setContent(xunit.getXML()); + test.assertEvalEquals(function() { + return __utils__.findAll('testsuite').length; + }, 2); + test.assertExists('testsuites[time]'); + test.assertExists('testsuite[name="foo"][package="foo"]'); + test.assertExists('testsuite[name="bar"][package="bar"]'); + test.done(); +}); + +casper.test.begin('XUnitReporter() can hold a suite with a succesful test', 1, function suite(test) { + var xunit = require('xunit').create(); + var results = new tester.TestSuiteResult(); + var suite1 = new tester.TestCaseResult({ + name: 'foo', + file: '/foo' + }); + suite1.addSuccess({ + success: true, + type: "footype", + message: "footext", + file: "/foo" + }); + results.push(suite1); + xunit.setResults(results); + casper.start().setContent(xunit.getXML()); + test.assertExists('testsuite[name="foo"][package="foo"][tests="1"][failures="0"] testcase[name="footext"]'); + test.done(); +}); + +casper.test.begin('XUnitReporter() can handle a failed test', 2, function suite(test) { + var xunit = require('xunit').create(); + var results = new tester.TestSuiteResult(); + var suite1 = new tester.TestCaseResult({ + name: 'foo', + file: '/foo' + }); + suite1.addFailure({ + success: false, + type: "footype", + message: "footext", + file: "/foo" + }); + results.push(suite1); + xunit.setResults(results); + casper.start().setContent(xunit.getXML()); + test.assertExists('testsuite[name="foo"][package="foo"][tests="1"][failures="1"] testcase[name="footext"] failure[type="footype"]'); + test.assertEquals(casper.getElementInfo('failure[type="footype"]').text, 'footext'); + test.done(); +}); diff --git a/vendor/casperjs/tests/testdir/01_a/abc.js b/vendor/casperjs/tests/testdir/01_a/abc.js new file mode 100755 index 0000000..e69de29 diff --git a/vendor/casperjs/tests/testdir/01_a/def.js b/vendor/casperjs/tests/testdir/01_a/def.js new file mode 100755 index 0000000..e69de29 diff --git a/vendor/casperjs/tests/testdir/02_b/abc.js b/vendor/casperjs/tests/testdir/02_b/abc.js new file mode 100755 index 0000000..e69de29 diff --git a/vendor/casperjs/tests/testdir/03_a.js b/vendor/casperjs/tests/testdir/03_a.js new file mode 100755 index 0000000..e69de29 diff --git a/vendor/casperjs/tests/testdir/03_b.js b/vendor/casperjs/tests/testdir/03_b.js new file mode 100755 index 0000000..e69de29 diff --git a/vendor/casperjs/tests/testdir/04/01_init.js b/vendor/casperjs/tests/testdir/04/01_init.js new file mode 100755 index 0000000..e69de29 diff --git a/vendor/casperjs/tests/testdir/04/02_do.js b/vendor/casperjs/tests/testdir/04/02_do.js new file mode 100755 index 0000000..e69de29 diff --git a/vendor/rusha.js b/vendor/rusha.js new file mode 100644 index 0000000..14b542a --- /dev/null +++ b/vendor/rusha.js @@ -0,0 +1,413 @@ +/* + * Rusha, a JavaScript implementation of the Secure Hash Algorithm, SHA-1, + * as defined in FIPS PUB 180-1, tuned for high performance with large inputs. + * (http://github.com/srijs/rusha) + * + * Inspired by Paul Johnstons implementation (http://pajhome.org.uk/crypt/md5). + * + * Copyright (c) 2013 Sam Rijs (http://awesam.de). + * Released under the terms of the MIT license as follows: + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ +(function () { + var util = { + getDataType: function (data) { + if (typeof data === 'string') { + return 'string'; + } + if (data instanceof Array) { + return 'array'; + } + if (typeof global !== 'undefined' && global.Buffer && global.Buffer.isBuffer(data)) { + return 'buffer'; + } + if (data instanceof ArrayBuffer) { + return 'arraybuffer'; + } + if (data.buffer instanceof ArrayBuffer) { + return 'view'; + } + if (data instanceof Blob) { + return 'blob'; + } + throw new Error('Unsupported data type.'); + } + }; + // The Rusha object is a wrapper around the low-level RushaCore. + // It provides means of converting different inputs to the + // format accepted by RushaCore as well as other utility methods. + function Rusha(chunkSize) { + 'use strict'; + // Private object structure. + var self$2 = { fill: 0 }; + // Calculate the length of buffer that the sha1 routine uses + // including the padding. + var padlen = function (len) { + for (len += 9; len % 64 > 0; len += 1); + return len; + }; + var padZeroes = function (bin, len) { + for (var i = len >> 2; i < bin.length; i++) + bin[i] = 0; + }; + var padData = function (bin, chunkLen, msgLen) { + bin[chunkLen >> 2] |= 128 << 24 - (chunkLen % 4 << 3); + bin[((chunkLen >> 2) + 2 & ~15) + 14] = msgLen >> 29; + bin[((chunkLen >> 2) + 2 & ~15) + 15] = msgLen << 3; + }; + // Convert a binary string and write it to the heap. + // A binary string is expected to only contain char codes < 256. + var convStr = function (H8, H32, start, len, off) { + var str = this, i, om = off % 4, lm = len % 4, j = len - lm; + if (j > 0) { + switch (om) { + case 0: + H8[off + 3 | 0] = str.charCodeAt(start); + case 1: + H8[off + 2 | 0] = str.charCodeAt(start + 1); + case 2: + H8[off + 1 | 0] = str.charCodeAt(start + 2); + case 3: + H8[off | 0] = str.charCodeAt(start + 3); + } + } + for (i = om; i < j; i = i + 4 | 0) { + H32[off + i >> 2] = str.charCodeAt(start + i) << 24 | str.charCodeAt(start + i + 1) << 16 | str.charCodeAt(start + i + 2) << 8 | str.charCodeAt(start + i + 3); + } + switch (lm) { + case 3: + H8[off + j + 1 | 0] = str.charCodeAt(start + j + 2); + case 2: + H8[off + j + 2 | 0] = str.charCodeAt(start + j + 1); + case 1: + H8[off + j + 3 | 0] = str.charCodeAt(start + j); + } + }; + // Convert a buffer or array and write it to the heap. + // The buffer or array is expected to only contain elements < 256. + var convBuf = function (H8, H32, start, len, off) { + var buf = this, i, om = off % 4, lm = len % 4, j = len - lm; + if (j > 0) { + switch (om) { + case 0: + H8[off + 3 | 0] = buf[start]; + case 1: + H8[off + 2 | 0] = buf[start + 1]; + case 2: + H8[off + 1 | 0] = buf[start + 2]; + case 3: + H8[off | 0] = buf[start + 3]; + } + } + for (i = 4 - om; i < j; i = i += 4 | 0) { + H32[off + i >> 2] = buf[start + i] << 24 | buf[start + i + 1] << 16 | buf[start + i + 2] << 8 | buf[start + i + 3]; + } + switch (lm) { + case 3: + H8[off + j + 1 | 0] = buf[start + j + 2]; + case 2: + H8[off + j + 2 | 0] = buf[start + j + 1]; + case 1: + H8[off + j + 3 | 0] = buf[start + j]; + } + }; + var convBlob = function (H8, H32, start, len, off) { + var blob = this, i, om = off % 4, lm = len % 4, j = len - lm; + var buf = new Uint8Array(reader.readAsArrayBuffer(blob.slice(start, start + len))); + if (j > 0) { + switch (om) { + case 0: + H8[off + 3 | 0] = buf[0]; + case 1: + H8[off + 2 | 0] = buf[1]; + case 2: + H8[off + 1 | 0] = buf[2]; + case 3: + H8[off | 0] = buf[3]; + } + } + for (i = 4 - om; i < j; i = i += 4 | 0) { + H32[off + i >> 2] = buf[i] << 24 | buf[i + 1] << 16 | buf[i + 2] << 8 | buf[i + 3]; + } + switch (lm) { + case 3: + H8[off + j + 1 | 0] = buf[j + 2]; + case 2: + H8[off + j + 2 | 0] = buf[j + 1]; + case 1: + H8[off + j + 3 | 0] = buf[j]; + } + }; + var convFn = function (data) { + switch (util.getDataType(data)) { + case 'string': + return convStr.bind(data); + case 'array': + return convBuf.bind(data); + case 'buffer': + return convBuf.bind(data); + case 'arraybuffer': + return convBuf.bind(new Uint8Array(data)); + case 'view': + return convBuf.bind(new Uint8Array(data.buffer, data.byteOffset, data.byteLength)); + case 'blob': + return convBlob.bind(data); + } + }; + var slice = function (data, offset) { + switch (util.getDataType(data)) { + case 'string': + return data.slice(offset); + case 'array': + return data.slice(offset); + case 'buffer': + return data.slice(offset); + case 'arraybuffer': + return data.slice(offset); + case 'view': + return data.buffer.slice(offset); + } + }; + // Convert an ArrayBuffer into its hexadecimal string representation. + var hex = function (arrayBuffer) { + var i, x, hex_tab = '0123456789abcdef', res = [], binarray = new Uint8Array(arrayBuffer); + for (i = 0; i < binarray.length; i++) { + x = binarray[i]; + res[i] = hex_tab.charAt(x >> 4 & 15) + hex_tab.charAt(x >> 0 & 15); + } + return res.join(''); + }; + var ceilHeapSize = function (v) { + // The asm.js spec says: + // The heap object's byteLength must be either + // 2^n for n in [12, 24) or 2^24 * n for n ≥ 1. + // Also, byteLengths smaller than 2^16 are deprecated. + var p; + // If v is smaller than 2^16, the smallest possible solution + // is 2^16. + if (v <= 65536) + return 65536; + // If v < 2^24, we round up to 2^n, + // otherwise we round up to 2^24 * n. + if (v < 16777216) { + for (p = 1; p < v; p = p << 1); + } else { + for (p = 16777216; p < v; p += 16777216); + } + return p; + }; + // Initialize the internal data structures to a new capacity. + var init = function (size) { + if (size % 64 > 0) { + throw new Error('Chunk size must be a multiple of 128 bit'); + } + self$2.maxChunkLen = size; + self$2.padMaxChunkLen = padlen(size); + // The size of the heap is the sum of: + // 1. The padded input message size + // 2. The extended space the algorithm needs (320 byte) + // 3. The 160 bit state the algoritm uses + self$2.heap = new ArrayBuffer(ceilHeapSize(self$2.padMaxChunkLen + 320 + 20)); + self$2.h32 = new Int32Array(self$2.heap); + self$2.h8 = new Int8Array(self$2.heap); + self$2.core = new Rusha._core({ + Int32Array: Int32Array, + DataView: DataView + }, {}, self$2.heap); + self$2.buffer = null; + }; + // Iinitializethe datastructures according + // to a chunk siyze. + init(chunkSize || 64 * 1024); + var initState = function (heap, padMsgLen) { + var io = new Int32Array(heap, padMsgLen + 320, 5); + io[0] = 1732584193; + io[1] = -271733879; + io[2] = -1732584194; + io[3] = 271733878; + io[4] = -1009589776; + }; + var padChunk = function (chunkLen, msgLen) { + var padChunkLen = padlen(chunkLen); + var view = new Int32Array(self$2.heap, 0, padChunkLen >> 2); + padZeroes(view, chunkLen); + padData(view, chunkLen, msgLen); + return padChunkLen; + }; + // Write data to the heap. + var write = function (data, chunkOffset, chunkLen) { + convFn(data)(self$2.h8, self$2.h32, chunkOffset, chunkLen, 0); + }; + // Initialize and call the RushaCore, + // assuming an input buffer of length len * 4. + var coreCall = function (data, chunkOffset, chunkLen, msgLen, finalize) { + var padChunkLen = chunkLen; + if (finalize) { + padChunkLen = padChunk(chunkLen, msgLen); + } + write(data, chunkOffset, chunkLen); + self$2.core.hash(padChunkLen, self$2.padMaxChunkLen); + }; + var getRawDigest = function (heap, padMaxChunkLen) { + var io = new Int32Array(heap, padMaxChunkLen + 320, 5); + var out = new Int32Array(5); + var arr = new DataView(out.buffer); + arr.setInt32(0, io[0], false); + arr.setInt32(4, io[1], false); + arr.setInt32(8, io[2], false); + arr.setInt32(12, io[3], false); + arr.setInt32(16, io[4], false); + return out; + }; + // Calculate the hash digest as an array of 5 32bit integers. + var rawDigest = this.rawDigest = function (str) { + var msgLen = str.byteLength || str.length || str.size || 0; + initState(self$2.heap, self$2.padMaxChunkLen); + var chunkOffset = 0, chunkLen = self$2.maxChunkLen, last; + for (chunkOffset = 0; msgLen > chunkOffset + chunkLen; chunkOffset += chunkLen) { + coreCall(str, chunkOffset, chunkLen, msgLen, false); + } + coreCall(str, chunkOffset, msgLen - chunkOffset, msgLen, true); + return getRawDigest(self$2.heap, self$2.padMaxChunkLen); + }; + // The digest and digestFrom* interface returns the hash digest + // as a hex string. + this.digest = this.digestFromString = this.digestFromBuffer = this.digestFromArrayBuffer = function (str) { + return hex(rawDigest(str).buffer); + }; + } + ; + // The low-level RushCore module provides the heart of Rusha, + // a high-speed sha1 implementation working on an Int32Array heap. + // At first glance, the implementation seems complicated, however + // with the SHA1 spec at hand, it is obvious this almost a textbook + // implementation that has a few functions hand-inlined and a few loops + // hand-unrolled. + Rusha._core = function RushaCore(stdlib, foreign, heap) { + 'use asm'; + var H = new stdlib.Int32Array(heap); + function hash(k, x) { + // k in bytes + k = k | 0; + x = x | 0; + var i = 0, j = 0, y0 = 0, z0 = 0, y1 = 0, z1 = 0, y2 = 0, z2 = 0, y3 = 0, z3 = 0, y4 = 0, z4 = 0, t0 = 0, t1 = 0; + y0 = H[x + 320 >> 2] | 0; + y1 = H[x + 324 >> 2] | 0; + y2 = H[x + 328 >> 2] | 0; + y3 = H[x + 332 >> 2] | 0; + y4 = H[x + 336 >> 2] | 0; + for (i = 0; (i | 0) < (k | 0); i = i + 64 | 0) { + z0 = y0; + z1 = y1; + z2 = y2; + z3 = y3; + z4 = y4; + for (j = 0; (j | 0) < 64; j = j + 4 | 0) { + t1 = H[i + j >> 2] | 0; + t0 = ((y0 << 5 | y0 >>> 27) + (y1 & y2 | ~y1 & y3) | 0) + ((t1 + y4 | 0) + 1518500249 | 0) | 0; + y4 = y3; + y3 = y2; + y2 = y1 << 30 | y1 >>> 2; + y1 = y0; + y0 = t0; + H[k + j >> 2] = t1; + } + for (j = k + 64 | 0; (j | 0) < (k + 80 | 0); j = j + 4 | 0) { + t1 = (H[j - 12 >> 2] ^ H[j - 32 >> 2] ^ H[j - 56 >> 2] ^ H[j - 64 >> 2]) << 1 | (H[j - 12 >> 2] ^ H[j - 32 >> 2] ^ H[j - 56 >> 2] ^ H[j - 64 >> 2]) >>> 31; + t0 = ((y0 << 5 | y0 >>> 27) + (y1 & y2 | ~y1 & y3) | 0) + ((t1 + y4 | 0) + 1518500249 | 0) | 0; + y4 = y3; + y3 = y2; + y2 = y1 << 30 | y1 >>> 2; + y1 = y0; + y0 = t0; + H[j >> 2] = t1; + } + for (j = k + 80 | 0; (j | 0) < (k + 160 | 0); j = j + 4 | 0) { + t1 = (H[j - 12 >> 2] ^ H[j - 32 >> 2] ^ H[j - 56 >> 2] ^ H[j - 64 >> 2]) << 1 | (H[j - 12 >> 2] ^ H[j - 32 >> 2] ^ H[j - 56 >> 2] ^ H[j - 64 >> 2]) >>> 31; + t0 = ((y0 << 5 | y0 >>> 27) + (y1 ^ y2 ^ y3) | 0) + ((t1 + y4 | 0) + 1859775393 | 0) | 0; + y4 = y3; + y3 = y2; + y2 = y1 << 30 | y1 >>> 2; + y1 = y0; + y0 = t0; + H[j >> 2] = t1; + } + for (j = k + 160 | 0; (j | 0) < (k + 240 | 0); j = j + 4 | 0) { + t1 = (H[j - 12 >> 2] ^ H[j - 32 >> 2] ^ H[j - 56 >> 2] ^ H[j - 64 >> 2]) << 1 | (H[j - 12 >> 2] ^ H[j - 32 >> 2] ^ H[j - 56 >> 2] ^ H[j - 64 >> 2]) >>> 31; + t0 = ((y0 << 5 | y0 >>> 27) + (y1 & y2 | y1 & y3 | y2 & y3) | 0) + ((t1 + y4 | 0) - 1894007588 | 0) | 0; + y4 = y3; + y3 = y2; + y2 = y1 << 30 | y1 >>> 2; + y1 = y0; + y0 = t0; + H[j >> 2] = t1; + } + for (j = k + 240 | 0; (j | 0) < (k + 320 | 0); j = j + 4 | 0) { + t1 = (H[j - 12 >> 2] ^ H[j - 32 >> 2] ^ H[j - 56 >> 2] ^ H[j - 64 >> 2]) << 1 | (H[j - 12 >> 2] ^ H[j - 32 >> 2] ^ H[j - 56 >> 2] ^ H[j - 64 >> 2]) >>> 31; + t0 = ((y0 << 5 | y0 >>> 27) + (y1 ^ y2 ^ y3) | 0) + ((t1 + y4 | 0) - 899497514 | 0) | 0; + y4 = y3; + y3 = y2; + y2 = y1 << 30 | y1 >>> 2; + y1 = y0; + y0 = t0; + H[j >> 2] = t1; + } + y0 = y0 + z0 | 0; + y1 = y1 + z1 | 0; + y2 = y2 + z2 | 0; + y3 = y3 + z3 | 0; + y4 = y4 + z4 | 0; + } + H[x + 320 >> 2] = y0; + H[x + 324 >> 2] = y1; + H[x + 328 >> 2] = y2; + H[x + 332 >> 2] = y3; + H[x + 336 >> 2] = y4; + } + return { hash: hash }; + }; + // If we'e running in Node.JS, export a module. + if (typeof module !== 'undefined') { + module.exports = Rusha; + } else if (typeof window !== 'undefined') { + window.Rusha = Rusha; + } + // If we're running in a webworker, accept + // messages containing a jobid and a buffer + // or blob object, and return the hash result. + if (typeof FileReaderSync !== 'undefined') { + var reader = new FileReaderSync(), hasher = new Rusha(4 * 1024 * 1024); + self.onmessage = function onMessage(event) { + var hash, data = event.data.data; + try { + hash = hasher.digest(data); + self.postMessage({ + id: event.data.id, + hash: hash + }); + } catch (e) { + self.postMessage({ + id: event.data.id, + error: e.name + }); + } + }; + } +}()); \ No newline at end of file