├── .gitmodules
├── tests
├── suites
│ ├── .casper
│ ├── casper
│ │ ├── .casper
│ │ ├── getplaintext.js
│ │ ├── exists.js
│ │ ├── prompt.js
│ │ ├── debug.js
│ │ ├── reload.js
│ │ ├── start.js
│ │ ├── callback.js
│ │ ├── global.js
│ │ ├── callutils.js
│ │ ├── location.js
│ │ ├── encode.js
│ │ ├── onerror.js
│ │ ├── history.js
│ │ ├── visible.js
│ │ ├── agent.js
│ │ ├── newpage.js
│ │ ├── auth.js
│ │ ├── scroll.js
│ │ ├── elementattribute.js
│ │ ├── alert.js
│ │ ├── flow.coffee
│ │ ├── headers.js
│ │ ├── scripts.js
│ │ ├── xpath.js
│ │ ├── content.js
│ │ ├── resources.js
│ │ ├── events.js
│ │ ├── request.js
│ │ ├── frames.js
│ │ ├── confirm.js
│ │ ├── capture.js
│ │ ├── navigation.js
│ │ ├── viewport.js
│ │ ├── encodedurl.js
│ │ ├── logging.js
│ │ ├── fetchtext.js
│ │ ├── urls.js
│ │ ├── steps.js
│ │ ├── mouseevents.js
│ │ ├── hooks.js
│ │ ├── keys.js
│ │ └── bypass.js
│ ├── tester
│ │ ├── .casper
│ │ ├── setup-teardown.js
│ │ ├── skip.js
│ │ ├── test-order.js
│ │ ├── setup-teardown-async.js
│ │ ├── begin-config.js
│ │ ├── testsuite.js
│ │ └── testcase.js
│ ├── coffee.coffee
│ ├── pagestack.js
│ ├── fs.js
│ ├── require.js
│ └── http_status.js
├── testdir
│ ├── 03_a.js
│ ├── 03_b.js
│ ├── 01_a
│ │ ├── abc.js
│ │ └── def.js
│ ├── 02_b
│ │ └── abc.js
│ └── 04
│ │ ├── 01_init.js
│ │ └── 02_do.js
├── site
│ ├── dummy.json
│ ├── dummy.txt
│ ├── dummy.js
│ ├── plaintext.notype
│ ├── images
│ │ └── phantom.png
│ ├── page1.html
│ ├── page2.html
│ ├── page3.html
│ ├── includes
│ │ ├── include1.js
│ │ └── include2.js
│ ├── test.html
│ ├── alert.html
│ ├── frame1.html
│ ├── error.html
│ ├── has%20space.html
│ ├── callback.html
│ ├── elementattribute.html
│ ├── field-file-multiple.html
│ ├── frame3.html
│ ├── confirm.html
│ ├── result.html
│ ├── frame2.html
│ ├── prompt.html
│ ├── frames.html
│ ├── global.html
│ ├── multiple-forms.html
│ ├── resources.html
│ ├── field-array.html
│ ├── visible.html
│ ├── urls.html
│ ├── index.html
│ ├── popup.html
│ ├── waitFor.html
│ ├── area.html
│ ├── mouse-events.html
│ └── click.html
├── sample_modules
│ ├── config.json
│ ├── csmodule.coffee
│ └── jsmodule.js
├── clitests
│ ├── modules
│ │ ├── sub
│ │ │ ├── mod.js
│ │ │ └── coffeemod.coffee
│ │ ├── node_modules
│ │ │ ├── bar.js
│ │ │ ├── json.json
│ │ │ ├── baz
│ │ │ │ ├── baz.js
│ │ │ │ └── package.json
│ │ │ └── foo
│ │ │ │ └── index.js
│ │ ├── test.js
│ │ ├── test_node_mod.js
│ │ ├── test_node_mod_index.js
│ │ ├── test_node_json.js
│ │ ├── test_node_mod_json_package.js
│ │ ├── test_node_subdir
│ │ │ └── test_node_mod.js
│ │ ├── test_coffee.js
│ │ ├── mod.js
│ │ └── test_patched_require.js
│ ├── error
│ │ └── syntax.js
│ ├── scripts
│ │ ├── script.js
│ │ └── options.js
│ ├── fail-fast
│ │ ├── standard
│ │ │ ├── test1.js
│ │ │ ├── test2.js
│ │ │ ├── test3.js
│ │ │ └── hook.js
│ │ └── manual-abort
│ │ │ └── index.js
│ └── tester
│ │ ├── failing.js
│ │ ├── passing.js
│ │ ├── dubious.js
│ │ ├── skipped.js
│ │ ├── exit.js
│ │ ├── step_throws.js
│ │ ├── casper-instance-override.js
│ │ ├── mytest.js
│ │ └── waitFor_timeout.js
└── selftest.js
├── .gitattributes
├── docs
├── _themes
│ └── casperjs
│ │ ├── theme.conf
│ │ ├── localtoc.html
│ │ ├── layout.html
│ │ ├── sourcelink.html
│ │ └── addon.html
├── _static
│ ├── images
│ │ ├── .npmignore
│ │ ├── bg.png
│ │ ├── demo.png
│ │ ├── tar.png
│ │ ├── zip.png
│ │ ├── forkme.png
│ │ ├── colorizer.png
│ │ ├── logoutput.png
│ │ ├── cow-test-ko.png
│ │ ├── cow-test-ok.png
│ │ ├── logo_casperjs.ai
│ │ ├── testsuiteok.png
│ │ ├── casperjs-logo.png
│ │ ├── logo_casperjs.eps
│ │ ├── logo_casperjs.pdf
│ │ ├── casperjs-rounded.png
│ │ ├── evaluate-diagram.png
│ │ ├── casperjs-logo-medium.png
│ │ ├── casperjs-logo-small.png
│ │ ├── casperjs-logo-xsmall.png
│ │ ├── split-test-results.png
│ │ ├── casperjs-logo-squared.png
│ │ └── casperjs-logo-squared-inv.png
│ └── casperjs-favicon.ico
├── upgrading
│ └── index.rst
├── changelog.rst
├── Makefile
├── README.md
├── modules
│ ├── index.rst
│ └── colorizer.rst
├── license.rst
├── index.rst
├── known_issues.rst
├── credits.rst
├── logging.rst
├── writing_modules.rst
└── selectors.rst
├── bin
├── casperjs.exe
└── usage.txt
├── CHANGELOG.md
├── .gitignore
├── .eslintignore
├── samples
├── download.coffee
├── logcolor.coffee
├── each.coffee
├── customevents.coffee
├── download.js
├── logcolor.js
├── statushandlers.coffee
├── customevents.js
├── each.js
├── cliplay.coffee
├── statushandlers.js
├── metaextract.coffee
├── translate.coffee
├── extends.coffee
├── metaextract.js
├── cliplay.js
├── translate.js
├── timeout.coffee
├── screenshot.coffee
├── events.coffee
├── extends.js
├── googlelinks.coffee
├── multirun.coffee
├── steptimeout.coffee
├── customlogging.coffee
├── screenshot.js
├── googletesting.coffee
├── events.js
├── timeout.js
├── customlogging.js
├── googlepagination.coffee
├── googlelinks.js
├── steptimeout.js
├── googlematch.coffee
├── googletesting.js
├── multirun.js
├── dynamic.coffee
├── googlepagination.js
├── googlematch.js
├── dynamic.js
├── bbcshots.coffee
└── bbcshots.js
├── Makefile
├── package.json
├── LICENSE.md
├── casperjs.gemspec
├── rpm
├── build
└── casperjs.spec
├── CONTRIBUTORS.md
└── modules
└── http.js
/.gitmodules:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/suites/.casper:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/testdir/03_a.js:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/testdir/03_b.js:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/suites/casper/.casper:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/suites/tester/.casper:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/testdir/01_a/abc.js:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/testdir/01_a/def.js:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/testdir/02_b/abc.js:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/testdir/04/01_init.js:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/testdir/04/02_do.js:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | * text=auto
2 |
--------------------------------------------------------------------------------
/tests/site/dummy.json:
--------------------------------------------------------------------------------
1 | {"dummy":"json"}
2 |
--------------------------------------------------------------------------------
/tests/site/dummy.txt:
--------------------------------------------------------------------------------
1 | some dummy text
2 |
--------------------------------------------------------------------------------
/tests/site/dummy.js:
--------------------------------------------------------------------------------
1 | document.write('foo');
2 |
--------------------------------------------------------------------------------
/tests/sample_modules/config.json:
--------------------------------------------------------------------------------
1 | {"ok": true}
2 |
--------------------------------------------------------------------------------
/tests/sample_modules/csmodule.coffee:
--------------------------------------------------------------------------------
1 | exports.ok = true
2 |
--------------------------------------------------------------------------------
/tests/sample_modules/jsmodule.js:
--------------------------------------------------------------------------------
1 | exports.ok = true;
2 |
--------------------------------------------------------------------------------
/tests/clitests/modules/sub/mod.js:
--------------------------------------------------------------------------------
1 | exports.name = 'world';
2 |
--------------------------------------------------------------------------------
/docs/_themes/casperjs/theme.conf:
--------------------------------------------------------------------------------
1 | [theme]
2 | inherit = basic
3 |
--------------------------------------------------------------------------------
/tests/clitests/modules/node_modules/bar.js:
--------------------------------------------------------------------------------
1 | module.exports = 42;
2 |
--------------------------------------------------------------------------------
/tests/clitests/modules/node_modules/json.json:
--------------------------------------------------------------------------------
1 | {"universe": 42}
2 |
--------------------------------------------------------------------------------
/tests/clitests/modules/sub/coffeemod.coffee:
--------------------------------------------------------------------------------
1 | module.exports = 42
2 |
--------------------------------------------------------------------------------
/tests/site/plaintext.notype:
--------------------------------------------------------------------------------
1 | This is a plain and very simple sentence.
--------------------------------------------------------------------------------
/tests/clitests/error/syntax.js:
--------------------------------------------------------------------------------
1 | qsfjdhf!èrè"èqwnfkmsghfkswjdgfjksn
2 |
--------------------------------------------------------------------------------
/tests/clitests/modules/node_modules/baz/baz.js:
--------------------------------------------------------------------------------
1 | module.exports = 42;
2 |
--------------------------------------------------------------------------------
/tests/clitests/modules/node_modules/foo/index.js:
--------------------------------------------------------------------------------
1 | module.exports = 42;
2 |
--------------------------------------------------------------------------------
/docs/_static/images/.npmignore:
--------------------------------------------------------------------------------
1 | .npmignore
2 | *.ai
3 | *.pdf
4 | *.eps
5 |
--------------------------------------------------------------------------------
/bin/casperjs.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tes/casperjs/master/bin/casperjs.exe
--------------------------------------------------------------------------------
/tests/clitests/modules/node_modules/baz/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "main": "baz.js"
3 | }
4 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | [This file has moved to Github](https://github.com/casperjs/casperjs/releases)
2 |
--------------------------------------------------------------------------------
/docs/_static/images/bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tes/casperjs/master/docs/_static/images/bg.png
--------------------------------------------------------------------------------
/docs/_static/images/demo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tes/casperjs/master/docs/_static/images/demo.png
--------------------------------------------------------------------------------
/docs/_static/images/tar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tes/casperjs/master/docs/_static/images/tar.png
--------------------------------------------------------------------------------
/docs/_static/images/zip.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tes/casperjs/master/docs/_static/images/zip.png
--------------------------------------------------------------------------------
/tests/site/images/phantom.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tes/casperjs/master/tests/site/images/phantom.png
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | /*.xml
3 | /*.png
4 | /docs/*.js
5 | /docs/*.xml
6 | /docs/_build
7 | /tmp
8 | *.pyc
9 |
--------------------------------------------------------------------------------
/docs/_static/images/forkme.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tes/casperjs/master/docs/_static/images/forkme.png
--------------------------------------------------------------------------------
/docs/upgrading/index.rst:
--------------------------------------------------------------------------------
1 | Upgrading
2 | =========
3 |
4 | .. toctree::
5 | :maxdepth: 1
6 |
7 | 1.1
8 |
--------------------------------------------------------------------------------
/docs/_static/casperjs-favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tes/casperjs/master/docs/_static/casperjs-favicon.ico
--------------------------------------------------------------------------------
/docs/_static/images/colorizer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tes/casperjs/master/docs/_static/images/colorizer.png
--------------------------------------------------------------------------------
/docs/_static/images/logoutput.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tes/casperjs/master/docs/_static/images/logoutput.png
--------------------------------------------------------------------------------
/docs/_static/images/cow-test-ko.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tes/casperjs/master/docs/_static/images/cow-test-ko.png
--------------------------------------------------------------------------------
/docs/_static/images/cow-test-ok.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tes/casperjs/master/docs/_static/images/cow-test-ok.png
--------------------------------------------------------------------------------
/docs/_static/images/logo_casperjs.ai:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tes/casperjs/master/docs/_static/images/logo_casperjs.ai
--------------------------------------------------------------------------------
/docs/_static/images/testsuiteok.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tes/casperjs/master/docs/_static/images/testsuiteok.png
--------------------------------------------------------------------------------
/docs/_static/images/casperjs-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tes/casperjs/master/docs/_static/images/casperjs-logo.png
--------------------------------------------------------------------------------
/docs/_static/images/logo_casperjs.eps:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tes/casperjs/master/docs/_static/images/logo_casperjs.eps
--------------------------------------------------------------------------------
/docs/_static/images/logo_casperjs.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tes/casperjs/master/docs/_static/images/logo_casperjs.pdf
--------------------------------------------------------------------------------
/tests/clitests/scripts/script.js:
--------------------------------------------------------------------------------
1 | var casper = require('casper').create();
2 | casper.echo('it works');
3 | casper.exit();
4 |
--------------------------------------------------------------------------------
/docs/_static/images/casperjs-rounded.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tes/casperjs/master/docs/_static/images/casperjs-rounded.png
--------------------------------------------------------------------------------
/docs/_static/images/evaluate-diagram.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tes/casperjs/master/docs/_static/images/evaluate-diagram.png
--------------------------------------------------------------------------------
/docs/_static/images/casperjs-logo-medium.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tes/casperjs/master/docs/_static/images/casperjs-logo-medium.png
--------------------------------------------------------------------------------
/docs/_static/images/casperjs-logo-small.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tes/casperjs/master/docs/_static/images/casperjs-logo-small.png
--------------------------------------------------------------------------------
/docs/_static/images/casperjs-logo-xsmall.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tes/casperjs/master/docs/_static/images/casperjs-logo-xsmall.png
--------------------------------------------------------------------------------
/docs/_static/images/split-test-results.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tes/casperjs/master/docs/_static/images/split-test-results.png
--------------------------------------------------------------------------------
/docs/_static/images/casperjs-logo-squared.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tes/casperjs/master/docs/_static/images/casperjs-logo-squared.png
--------------------------------------------------------------------------------
/docs/_static/images/casperjs-logo-squared-inv.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tes/casperjs/master/docs/_static/images/casperjs-logo-squared-inv.png
--------------------------------------------------------------------------------
/tests/clitests/fail-fast/standard/test1.js:
--------------------------------------------------------------------------------
1 | casper.test.begin('test 1', 1, function(test) {
2 | test.assert(true);
3 | test.done();
4 | });
5 |
--------------------------------------------------------------------------------
/tests/clitests/fail-fast/standard/test2.js:
--------------------------------------------------------------------------------
1 | casper.test.begin('test 2', 1, function(test) {
2 | test.assert(false);
3 | test.done();
4 | });
5 |
--------------------------------------------------------------------------------
/tests/clitests/fail-fast/standard/test3.js:
--------------------------------------------------------------------------------
1 | casper.test.begin('test 3', 1, function(test) {
2 | test.assert(true);
3 | test.done();
4 | });
5 |
--------------------------------------------------------------------------------
/tests/clitests/modules/test.js:
--------------------------------------------------------------------------------
1 | var casper = require('casper').create();
2 | var mod = require('./mod');
3 | console.log(mod.hello);
4 | casper.exit();
5 |
--------------------------------------------------------------------------------
/tests/clitests/modules/test_node_mod.js:
--------------------------------------------------------------------------------
1 | var casper = require('casper').create();
2 | var foo = require('foo');
3 | console.log(foo);
4 | casper.exit();
5 |
--------------------------------------------------------------------------------
/tests/clitests/modules/test_node_mod_index.js:
--------------------------------------------------------------------------------
1 | var casper = require('casper').create();
2 | var bar = require('bar');
3 | console.log(bar);
4 | casper.exit();
5 |
--------------------------------------------------------------------------------
/tests/clitests/tester/failing.js:
--------------------------------------------------------------------------------
1 | /*eslint strict:0*/
2 | casper.test.begin('true', 1, function(test) {
3 | test.assert(false);
4 | test.done();
5 | });
6 |
--------------------------------------------------------------------------------
/tests/clitests/tester/passing.js:
--------------------------------------------------------------------------------
1 | /*eslint strict:0*/
2 | casper.test.begin('true', 1, function(test) {
3 | test.assert(true);
4 | test.done();
5 | });
6 |
--------------------------------------------------------------------------------
/tests/clitests/modules/test_node_json.js:
--------------------------------------------------------------------------------
1 | var casper = require('casper').create();
2 | var json = require('json');
3 | console.log(json.universe);
4 | casper.exit();
5 |
--------------------------------------------------------------------------------
/tests/clitests/modules/test_node_mod_json_package.js:
--------------------------------------------------------------------------------
1 | var casper = require('casper').create();
2 | var baz = require('baz');
3 | console.log(baz);
4 | casper.exit();
5 |
--------------------------------------------------------------------------------
/tests/clitests/modules/test_node_subdir/test_node_mod.js:
--------------------------------------------------------------------------------
1 | var casper = require('casper').create();
2 | var foo = require('foo');
3 | console.log(foo);
4 | casper.exit();
5 |
--------------------------------------------------------------------------------
/tests/clitests/tester/dubious.js:
--------------------------------------------------------------------------------
1 | /*eslint strict:0*/
2 | casper.test.begin('dubious test', 2, function(test) {
3 | test.assert(true);
4 | test.done();
5 | });
6 |
--------------------------------------------------------------------------------
/docs/_themes/casperjs/localtoc.html:
--------------------------------------------------------------------------------
1 | {%- if display_toc %}
2 |
3 | {{ toc }}
4 | {%- endif %}
5 |
--------------------------------------------------------------------------------
/tests/clitests/modules/test_coffee.js:
--------------------------------------------------------------------------------
1 | var casper = require('casper').create();
2 | var coffeemod = require('./sub/coffeemod');
3 | console.log(coffeemod);
4 | casper.exit();
5 |
--------------------------------------------------------------------------------
/docs/changelog.rst:
--------------------------------------------------------------------------------
1 | Changelog
2 | =========
3 |
4 | The CasperJS changelog is `hosted on github `_.
5 |
--------------------------------------------------------------------------------
/tests/clitests/tester/skipped.js:
--------------------------------------------------------------------------------
1 | /*eslint strict:0*/
2 | casper.test.begin('skipped test', 2, function(test) {
3 | test.skip(1);
4 | test.assert(true);
5 | test.done();
6 | });
7 |
--------------------------------------------------------------------------------
/docs/Makefile:
--------------------------------------------------------------------------------
1 | .PHONY: all default
2 |
3 | default: all
4 |
5 | all: build open
6 |
7 | build:
8 | sphinx-build . _build
9 |
10 | open:
11 | open _build/index.html
12 |
13 |
14 |
--------------------------------------------------------------------------------
/docs/README.md:
--------------------------------------------------------------------------------
1 | CasperJS Sphinx Documentation
2 | =============================
3 |
4 | Sphinx documentation for [CasperJS](http://casperjs.org/) 1.1-DEV and future
5 | versions. Work in progress.
6 |
--------------------------------------------------------------------------------
/tests/clitests/modules/mod.js:
--------------------------------------------------------------------------------
1 | /*global patchRequire*/
2 | var require = patchRequire(require);
3 | var utils = require('utils');
4 | exports.hello = utils.format('hello, %s', require('./sub/mod').name);
5 |
--------------------------------------------------------------------------------
/tests/clitests/scripts/options.js:
--------------------------------------------------------------------------------
1 | var require = patchRequire(require);
2 | var casper = require('casper').create();
3 | var utils = require('utils');
4 | utils.dump(casper.cli.options);
5 | casper.exit();
6 |
--------------------------------------------------------------------------------
/tests/clitests/modules/test_patched_require.js:
--------------------------------------------------------------------------------
1 | var require = patchRequire(require);
2 | var casper = require('casper').create();
3 | var mod = require('./mod');
4 | console.log(mod.hello);
5 | casper.exit();
6 |
--------------------------------------------------------------------------------
/tests/clitests/tester/exit.js:
--------------------------------------------------------------------------------
1 | casper.test.on("exit", function() {
2 | console.log("exited");
3 | })
4 |
5 | casper.test.begin("sample", function(test) {
6 | test.assert(true);
7 | test.done();
8 | });
9 |
--------------------------------------------------------------------------------
/tests/site/page1.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CasperJS test page 1
6 |
7 | Booh.
8 |
--------------------------------------------------------------------------------
/tests/site/page2.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CasperJS test page 2
6 |
7 | Booh.
8 |
--------------------------------------------------------------------------------
/tests/site/page3.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CasperJS test page 1
6 |
7 | Booh.
8 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | docs
2 | modules/vendors
3 | modules/events.js
4 | modules/querystring.js
5 | samples/**
6 | tests/**
7 | tests/clitests/**
8 | tests/testdir/**
9 | tests/suites/**
10 | tests/site/**
11 | tmp
12 | ./*.js
13 | ./phantomjs*/*
14 | ./engine/*
15 |
--------------------------------------------------------------------------------
/tests/clitests/fail-fast/standard/hook.js:
--------------------------------------------------------------------------------
1 | /* global casper */
2 |
3 | casper.test.on('fail', function doSomething() {
4 | 'use strict';
5 | casper.echo('fail event fired!');
6 | });
7 | casper.test.begin('hook', 0, function(t) {
8 | 'use strict';
9 | t.done();
10 | });
11 |
--------------------------------------------------------------------------------
/tests/site/includes/include1.js:
--------------------------------------------------------------------------------
1 | (function() {
2 | "use strict";
3 | var elem = document.createElement('div');
4 | elem.setAttribute('id', 'include1');
5 | elem.appendChild(document.createTextNode('include1'));
6 | document.querySelector('body').appendChild(elem);
7 | })();
8 |
--------------------------------------------------------------------------------
/tests/site/includes/include2.js:
--------------------------------------------------------------------------------
1 | (function() {
2 | "use strict";
3 | var elem = document.createElement('div');
4 | elem.setAttribute('id', 'include2');
5 | elem.appendChild(document.createTextNode('include2'));
6 | document.querySelector('body').appendChild(elem);
7 | })();
8 |
--------------------------------------------------------------------------------
/tests/site/test.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CasperJS test target
6 |
7 |
8 | test form
9 |
10 |
--------------------------------------------------------------------------------
/samples/download.coffee:
--------------------------------------------------------------------------------
1 | ###
2 | Download the google logo image onto the local filesystem
3 | ###
4 |
5 | casper = require("casper").create()
6 |
7 | casper.start "http://www.google.fr/", ->
8 | @echo @download "http://www.google.fr/images/srpr/logo3w.png", "logo.png"
9 |
10 | casper.run()
11 |
--------------------------------------------------------------------------------
/tests/clitests/tester/step_throws.js:
--------------------------------------------------------------------------------
1 | /*eslint strict:0*/
2 | casper.test.begin('step throws', 1, function(test) {
3 | casper.start();
4 | casper.then(function() {
5 | throw new Error('oops!')
6 | });
7 | casper.run(function() {
8 | test.done();
9 | })
10 | });
11 |
--------------------------------------------------------------------------------
/tests/site/alert.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CasperJS test alert
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/tests/site/frame1.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CasperJS frame 1
6 |
7 |
8 | This is frame 1.
9 |
10 |
11 |
--------------------------------------------------------------------------------
/samples/logcolor.coffee:
--------------------------------------------------------------------------------
1 | casper = require("casper").create
2 | verbose: true
3 | logLevel: "debug"
4 |
5 | casper.log "this is a debug message", "debug"
6 | casper.log "and an informative one", "info"
7 | casper.log "and a warning", "warning"
8 | casper.log "and an error", "error"
9 |
10 | casper.exit()
11 |
--------------------------------------------------------------------------------
/samples/each.coffee:
--------------------------------------------------------------------------------
1 | casper = require("casper").create()
2 |
3 | links = [
4 | "http://google.com/"
5 | "http://yahoo.com/"
6 | "http://bing.com/"
7 | ]
8 |
9 | casper.start()
10 |
11 | casper.each links, (self, link) ->
12 | @thenOpen link, -> @echo "#{@getTitle()} - #{link}"
13 |
14 | casper.run()
15 |
--------------------------------------------------------------------------------
/tests/site/error.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CasperJS error test
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/tests/site/has%20space.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CasperJS test url with encoded space
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/tests/site/callback.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CasperJS test callback
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/tests/clitests/tester/casper-instance-override.js:
--------------------------------------------------------------------------------
1 | // this should never happen
2 | // http://docs.casperjs.org/en/latest/testing.html#test-command-args-and-options
3 | var casper = require("casper").create();
4 |
5 | casper.test.begin("foo", function(test) {
6 | "use strict";
7 | test.assert(true);
8 | test.done();
9 | });
10 |
--------------------------------------------------------------------------------
/tests/site/elementattribute.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/samples/customevents.coffee:
--------------------------------------------------------------------------------
1 | casper = require("casper").create()
2 |
3 | # listening to a custom event
4 | casper.on "google.loaded", (title) ->
5 | @echo "Google page title is #{title}"
6 |
7 | casper.start "http://google.com/", ->
8 | # emitting a custom event
9 | @emit "google.loaded", @getTitle()
10 |
11 | casper.run()
12 |
--------------------------------------------------------------------------------
/tests/site/field-file-multiple.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Form field file multiple test
5 |
6 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/tests/site/frame3.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CasperJS frame 3
6 |
7 |
8 | This is frame 3.
9 | frame 2
10 |
11 |
12 |
--------------------------------------------------------------------------------
/tests/site/confirm.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CasperJS test confirm
6 |
7 |
8 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/tests/site/result.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CasperJS test form result
6 |
7 |
8 | this is the result page
9 | Return back home
10 |
11 |
--------------------------------------------------------------------------------
/tests/clitests/tester/mytest.js:
--------------------------------------------------------------------------------
1 | /*eslint strict:0*/
2 | /*global CasperError casper console phantom require*/
3 | casper.start('about:blank', function() {
4 | this.test.pass('ok1');
5 | });
6 |
7 | casper.then(function() {
8 | this.test.pass('ok2');
9 | });
10 |
11 | casper.run(function() {
12 | this.test.pass('ok3');
13 | this.test.done();
14 | });
15 |
--------------------------------------------------------------------------------
/tests/site/frame2.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CasperJS frame 2
6 |
7 |
8 | This is frame 2.
9 | frame 3
10 |
11 |
12 |
--------------------------------------------------------------------------------
/tests/site/prompt.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CasperJS test prompt
6 |
7 |
8 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/docs/modules/index.rst:
--------------------------------------------------------------------------------
1 | .. _modules_index:
2 |
3 | .. index:: modules
4 |
5 | =================
6 | API Documentation
7 | =================
8 |
9 | Here you'll find a quite complete reference of the CasperJS API. If something is erroneous or missing, please `file an issue `_.
10 |
11 | .. toctree::
12 | :glob:
13 |
14 | *
15 |
--------------------------------------------------------------------------------
/tests/site/frames.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CasperJS test frames
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/tests/site/global.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/samples/download.js:
--------------------------------------------------------------------------------
1 | /*eslint strict:0*/
2 | /*global CasperError, console, phantom, require*/
3 |
4 | /**
5 | * download the google logo image onto the local filesystem
6 | */
7 |
8 | var casper = require("casper").create();
9 |
10 | casper.start("http://www.google.fr/", function() {
11 | this.download("http://www.google.fr/images/srpr/logo3w.png", "logo.png");
12 | });
13 |
14 | casper.run();
15 |
--------------------------------------------------------------------------------
/samples/logcolor.js:
--------------------------------------------------------------------------------
1 | /*eslint strict:0*/
2 | /*global CasperError, console, phantom, require*/
3 |
4 | var casper = require("casper").create({
5 | verbose: true,
6 | logLevel: "debug"
7 | });
8 |
9 | casper.log("this is a debug message", "debug");
10 | casper.log("and an informative one", "info");
11 | casper.log("and a warning", "warning");
12 | casper.log("and an error", "error");
13 |
14 | casper.exit();
15 |
--------------------------------------------------------------------------------
/tests/site/multiple-forms.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Multiple forms test
5 |
6 |
7 |
11 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/tests/suites/casper/getplaintext.js:
--------------------------------------------------------------------------------
1 | /*eslint strict:0*/
2 | casper.test.begin('getPlainText() tests', 1, function(test) {
3 | casper.start('tests/site/plaintext.notype', function() {
4 | test.assertEquals(this.getPlainText(), 'This is a plain and very simple sentence.',
5 | 'Casper.getPlainText() can retrieve plain text with no content type');
6 | }).run(function() {
7 | test.done();
8 | });
9 | });
10 |
--------------------------------------------------------------------------------
/samples/statushandlers.coffee:
--------------------------------------------------------------------------------
1 | ###
2 | This script will add a custom HTTP status code handler, here for 404 pages.
3 | ###
4 |
5 | casper = require("casper").create
6 | httpStatusHandlers:
7 | 404: (self, resource) ->
8 | @echo "Resource at #{resource.url} not found (404)", "COMMENT"
9 | verbose: true
10 |
11 | casper.start "http://www.google.com/plop", ->
12 | @echo "Done."
13 | @exit()
14 |
15 | casper.run()
16 |
--------------------------------------------------------------------------------
/tests/suites/casper/exists.js:
--------------------------------------------------------------------------------
1 | /*eslint strict:0*/
2 | casper.test.begin('exists() tests', 2, function(test) {
3 | casper.start('tests/site/index.html', function() {
4 | test.assert(this.exists('a'), 'Casper.exists() can check if an element exists');
5 | test.assertNot(this.exists('chucknorriz'), 'Casper.exists() can check than an element does not exist');
6 | }).run(function() {
7 | test.done();
8 | });
9 | });
10 |
--------------------------------------------------------------------------------
/tests/suites/casper/prompt.js:
--------------------------------------------------------------------------------
1 | /*eslint strict:0*/
2 | casper.test.begin('prompt tests', 1, function(test) {
3 | casper.setFilter('page.prompt', function(message, value) {
4 | return 'Chuck ' + value;
5 | });
6 | casper.start('tests/site/prompt.html', function() {
7 | test.assertEquals(this.getGlobal('username'), 'Chuck Norris', 'prompted value has been received');
8 | }).run(function() {
9 | test.done();
10 | });
11 | });
12 |
--------------------------------------------------------------------------------
/samples/customevents.js:
--------------------------------------------------------------------------------
1 | /*eslint strict:0*/
2 | /*global CasperError, console, phantom, require*/
3 |
4 | var casper = require("casper").create();
5 |
6 | // listening to a custom event
7 | casper.on("google.loaded", function(title) {
8 | this.echo("Google page title is " + title);
9 | });
10 |
11 | casper.start("http://google.com/", function() {
12 | // emitting a custom event
13 | this.emit("google.loaded", this.getTitle());
14 | });
15 |
16 | casper.run();
17 |
--------------------------------------------------------------------------------
/samples/each.js:
--------------------------------------------------------------------------------
1 | /*eslint strict:0*/
2 | /*global CasperError, console, phantom, require*/
3 |
4 | var casper = require("casper").create();
5 |
6 | var links = [
7 | "http://google.com/",
8 | "http://yahoo.com/",
9 | "http://bing.com/"
10 | ];
11 |
12 | casper.start();
13 |
14 | casper.each(links, function(self, link) {
15 | this.thenOpen(link, function() {
16 | this.echo(this.getTitle() + " - " + link);
17 | });
18 | });
19 |
20 | casper.run();
21 |
--------------------------------------------------------------------------------
/tests/site/resources.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CasperJS test resource
6 |
7 |
8 |
9 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/tests/suites/casper/debug.js:
--------------------------------------------------------------------------------
1 | /*eslint strict:0*/
2 | casper.test.begin('getHTML() tests', 2, function(test) {
3 | casper.start('tests/site/index.html', function() {
4 | test.assertEquals(this.getHTML('ul li'), 'one',
5 | 'Casper.getHTML() retrieves inner HTML by default');
6 | test.assertEquals(this.getHTML('ul li', true), 'one ',
7 | 'Casper.getHTML() can retrieve outer HTML');
8 | }).run(function() {
9 | test.done();
10 | });
11 | });
12 |
--------------------------------------------------------------------------------
/tests/clitests/fail-fast/manual-abort/index.js:
--------------------------------------------------------------------------------
1 | casper.test.begin('test abort()', 10, function(test) {
2 | "use strict";
3 | for (var i = 0; i < 10; i++) {
4 | test.assert(true, 'test ' + (i + 1));
5 | if (i === 4) {
6 | test.abort('this is my abort message');
7 | }
8 | }
9 | test.done();
10 | });
11 |
12 | casper.test.begin('should not being executed', 1, function(test) {
13 | "use strict";
14 | test.fail('damn.');
15 | test.done();
16 | });
17 |
--------------------------------------------------------------------------------
/tests/site/field-array.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CasperJS test form
6 |
7 |
8 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/bin/usage.txt:
--------------------------------------------------------------------------------
1 | Usage: casperjs [options] script.[js|coffee] [script argument [script argument ...]]
2 | casperjs [options] test [test path [test path ...]]
3 | casperjs [options] selftest
4 |
5 | Options:
6 |
7 | --verbose Prints log messages to the console
8 | --log-level Sets logging level
9 | --help Prints this help
10 | --version Prints out CasperJS version
11 | --engine=name Use the given engine. Current supported engine: phantomjs and slimerjs
12 |
13 | Read the docs http://docs.casperjs.org/
14 |
--------------------------------------------------------------------------------
/docs/_themes/casperjs/layout.html:
--------------------------------------------------------------------------------
1 | {%- extends "basic/layout.html" %}
2 | {% block extrahead %}
3 |
4 |
5 |
6 |
7 | {% endblock extrahead %}
8 |
--------------------------------------------------------------------------------
/samples/cliplay.coffee:
--------------------------------------------------------------------------------
1 | casper = require("casper").create()
2 | dump = require("utils").dump
3 |
4 | # removing default options passed by the Python executable
5 | casper.cli.drop "cli"
6 | casper.cli.drop "casper-path"
7 |
8 | if casper.cli.args.length is 0 and Object.keys(casper.cli.options).length is 0
9 | casper
10 | .echo("Pass some args and options to see how they are handled by CasperJS")
11 | .exit(1)
12 |
13 | casper.echo "Casper CLI passed args:"
14 | dump casper.cli.args
15 |
16 | casper.echo "Casper CLI passed options:"
17 | dump casper.cli.options
18 |
19 | casper.exit()
20 |
--------------------------------------------------------------------------------
/samples/statushandlers.js:
--------------------------------------------------------------------------------
1 | /*eslint strict:0*/
2 | /*global CasperError, console, phantom, require*/
3 |
4 | /**
5 | * This script will add a custom HTTP status code handler, here for 404 pages.
6 | */
7 |
8 | var casper = require("casper").create({
9 | httpStatusHandlers: {
10 | 404: function(self, resource) {
11 | this.echo("Resource at " + resource.url + " not found (404)", "COMMENT");
12 | }
13 | },
14 | verbose: true
15 | });
16 |
17 | casper.start("http://www.google.com/plop", function() {
18 | this.echo("Done.");
19 | this.exit();
20 | });
21 |
22 | casper.run();
23 |
--------------------------------------------------------------------------------
/tests/suites/casper/reload.js:
--------------------------------------------------------------------------------
1 | /*eslint strict:0, max-statements:0*/
2 |
3 | casper.test.begin('reload() tests', 3, function(test) {
4 | var formUrl = 'tests/site/form.html';
5 |
6 | casper.start(formUrl, function() {
7 | this.fill("form", {email: "foo@foo.com"}, false);
8 | });
9 | casper.once("page.resource.requested", function(resource) {
10 | test.assert(resource.url.indexOf(formUrl) > 0);
11 | }).reload(function() {
12 | test.assertUrlMatches(formUrl);
13 | test.assertField("email", "");
14 | }).run(function() {
15 | test.done();
16 | });
17 | });
18 |
--------------------------------------------------------------------------------
/tests/site/visible.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CasperJS test index
6 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/tests/site/urls.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CasperJS url tests
6 |
7 |
8 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/tests/suites/casper/start.js:
--------------------------------------------------------------------------------
1 | /*eslint strict:0*/
2 | casper.test.begin('start() tests', 4, function(test) {
3 | casper.start('tests/site/index.html', function() {
4 | test.pass('Casper.start() can chain a next step');
5 | test.assertTitle('CasperJS test index', 'Casper.start() opened the passed url');
6 | test.assertEval(function() {
7 | return typeof(__utils__) === "object";
8 | }, 'Casper.start() injects ClientUtils instance within remote DOM');
9 | });
10 |
11 | test.assert(casper.started, 'Casper.start() started');
12 |
13 | casper.run(function() {
14 | test.done();
15 | });
16 | });
17 |
--------------------------------------------------------------------------------
/tests/suites/tester/setup-teardown.js:
--------------------------------------------------------------------------------
1 | /*eslint strict:0*/
2 |
3 | var setUp, tearDown;
4 |
5 | casper.test.setUp(function() {
6 | setUp = true;
7 | });
8 |
9 | casper.test.tearDown(function() {
10 | tearDown = true;
11 | // reset
12 | casper.test.setUp();
13 | casper.test.tearDown();
14 | });
15 |
16 | casper.test.begin('setUp() tests', 1, function(test) {
17 | test.assertTrue(setUp, 'Tester.setUp() executed the setup function');
18 | test.done();
19 | });
20 |
21 | casper.test.begin('tearDown() tests', 1, function(test) {
22 | test.assertTrue(tearDown, 'Tester.tearDown() executed the tear down function');
23 | test.done();
24 | });
25 |
--------------------------------------------------------------------------------
/samples/metaextract.coffee:
--------------------------------------------------------------------------------
1 | casper = require("casper").create()
2 | url = casper.cli.get 0
3 | metas = []
4 |
5 | if not url
6 | casper
7 | .echo("Usage: $ casperjs metaextract.coffee ")
8 | .exit 1
9 |
10 | casper.start url, ->
11 | metas = @evaluate ->
12 | metas = []
13 | castarray = (arr) -> [].slice.call(arr)
14 | for elem in castarray document.querySelectorAll "meta"
15 | meta = {}
16 | for attr in castarray elem.attributes
17 | meta[attr.name] = attr.value
18 | metas.push meta
19 | metas
20 |
21 | casper.run ->
22 | require("utils").dump metas
23 | this.exit()
24 |
--------------------------------------------------------------------------------
/tests/suites/casper/callback.js:
--------------------------------------------------------------------------------
1 | /*eslint strict:0*/
2 | casper.test.begin('callback events', 1, {
3 | ok: false,
4 |
5 | tearDown: function(test) {
6 | casper.removeAllListeners('remote.callback');
7 | },
8 |
9 | test: function(test) {
10 | var self = this;
11 |
12 | casper.once('remote.callback', function(data) {
13 | self.ok = (data.hello === 'world');
14 | });
15 |
16 | casper.start('tests/site/callback.html', function() {
17 | test.assert(self.ok, 'callback event has been intercepted');
18 | });
19 |
20 | casper.run(function() {
21 | test.done();
22 | });
23 | }
24 | });
25 |
--------------------------------------------------------------------------------
/tests/suites/casper/global.js:
--------------------------------------------------------------------------------
1 | /*eslint strict:0*/
2 | casper.test.begin('getGLobal() tests', 3, function(test) {
3 | casper.start('tests/site/global.html', function() {
4 | test.assertEquals(this.getGlobal('myGlobal'), 'awesome string',
5 | 'Casper.getGlobal() can retrieve a remote global variable');
6 | test.assertEquals(this.getGlobal('myObject').foo.bar, 'baz',
7 | 'Casper.getGlobal() can retrieves a serializable object');
8 | test.assertRaises(this.getGlobal, ['myUnencodableGlobal'],
9 | 'Casper.getGlobal() does not fail trying to encode an unserializable global');
10 | }).run(function() {
11 | test.done();
12 | });
13 | });
14 |
--------------------------------------------------------------------------------
/tests/site/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CasperJS test index
6 |
7 |
8 |
9 | test
10 | form
11 |
12 | one
13 | two
14 | three
15 |
16 |
17 | Title
18 | I'm hidden.
19 | Exports
20 |
21 |
22 |
--------------------------------------------------------------------------------
/tests/site/popup.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CasperJS test popup
6 |
7 |
8 | new window
9 | close
10 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | .PHONY: default test test-dotNET docs selftest compile-dotNET selftest-dotNET clitest clitest-dotNET lint
2 |
3 | default: test
4 |
5 | test: selftest clitest lint
6 |
7 | test-dotNET: compile-dotNET selftest-dotNET clitest-dotNET lint
8 |
9 | docs:
10 | sphinx-build -b html ./docs docs/_build
11 |
12 | selftest:
13 | bin/casperjs --help
14 | bin/casperjs selftest
15 |
16 | compile-dotNET:
17 | mcs -langversion:3 -out:bin/casperjs.exe src/casperjs.cs
18 |
19 | selftest-dotNET:
20 | mono bin/casperjs.exe --help
21 | mono bin/casperjs.exe selftest
22 |
23 | clitest:
24 | python tests/clitests/runtests.py
25 |
26 | clitest-dotNET:
27 | python tests/clitests/runtests.py casperjs.exe
28 |
29 | lint:
30 | eslint .
31 |
--------------------------------------------------------------------------------
/samples/translate.coffee:
--------------------------------------------------------------------------------
1 | ###
2 | Translation using the Google Translate Service.
3 |
4 | Usage:
5 |
6 | $ casperjs translate.coffee --target=fr "hello world"
7 | bonjour tout le monde
8 | ###
9 | system = require("system")
10 | casper = require("casper").create()
11 | format = require("utils").format
12 | source = casper.cli.get("source") or "auto"
13 | target = casper.cli.get("target")
14 | text = casper.cli.get(0)
15 | result = undefined
16 |
17 | casper.warn("The --target option is mandatory.").exit 1 unless target
18 |
19 | casper.start(format("http://translate.google.com/#%s/%s/%s", source, target, text), ->
20 | @fill "form#gt-form", text: text
21 | ).waitForSelector "span.hps", -> @echo @fetchText("#result_box")
22 |
23 | casper.run()
24 |
--------------------------------------------------------------------------------
/samples/extends.coffee:
--------------------------------------------------------------------------------
1 | casper = require("casper").create
2 | loadImages: false
3 | logLevel: "debug"
4 | verbose: true
5 |
6 | links =
7 | "http://edition.cnn.com/": 0
8 | "http://www.nytimes.com/": 0
9 | "http://www.bbc.co.uk/": 0
10 | "http://www.guardian.co.uk/": 0
11 |
12 | fantomas = Object.create(casper)
13 |
14 | fantomas.countLinks = ->
15 | @evaluate ->
16 | __utils__.findAll("a[href]").length
17 |
18 | fantomas.renderJSON = (what) ->
19 | @echo JSON.stringify(what, null, " ")
20 |
21 | fantomas.start()
22 |
23 | Object.keys(links).forEach (url) ->
24 | fantomas.thenOpen url, ->
25 | links[url] = @countLinks()
26 |
27 | fantomas.run ->
28 | @renderJSON(links)
29 | @exit()
30 |
--------------------------------------------------------------------------------
/tests/suites/tester/skip.js:
--------------------------------------------------------------------------------
1 | /*eslint strict:0*/
2 | casper.test.begin('Skip tests after', 4, function(test) {
3 | test.assert(true, 'First test executed');
4 | test.assert(true, 'Second test executed');
5 | test.skip(2, 'Two tests skipped');
6 | test.done();
7 | });
8 |
9 | casper.test.begin('Skip tests before', 4, function(test) {
10 | test.skip(2, 'Two tests skipped');
11 | test.assert(true, 'Third test executed');
12 | test.assert(true, 'Fourth test executed');
13 | test.done();
14 | });
15 |
16 | casper.test.begin('Skip tests (asynchronous)', 1, function(test) {
17 | casper.start('tests/site/index.html', function() {
18 | test.skip(1);
19 | }).run(function() {
20 | test.done();
21 | });
22 | });
23 |
--------------------------------------------------------------------------------
/docs/_themes/casperjs/sourcelink.html:
--------------------------------------------------------------------------------
1 | Index
2 | Thesaurus
3 |
4 | {%- if show_source and has_source and sourcename %}
5 | {{ _('This Page') }}
6 |
16 | {%- endif %}
17 |
--------------------------------------------------------------------------------
/tests/suites/tester/test-order.js:
--------------------------------------------------------------------------------
1 | /*eslint strict:0*/
2 | /*global CasperError, casper, console, phantom, require*/
3 | var fs = require('fs');
4 |
5 | casper.test.begin('Tester.sortFiles()', 1, function suite(test) {
6 | var testDirRoot = fs.pathJoin(phantom.casperPath, 'tests', 'testdir');
7 | var files = test.findTestFiles(testDirRoot);
8 | var expected = [
9 | "01_a/abc.js",
10 | "01_a/def.js",
11 | "02_b/abc.js",
12 | "03_a.js",
13 | "03_b.js",
14 | "04/01_init.js",
15 | "04/02_do.js"
16 | ].map(function(entry) {
17 | return fs.pathJoin.apply(fs, [testDirRoot].concat(entry.split('/')));
18 | });
19 | test.assertEquals(files, expected, 'findTestFiles() find test files and sort them');
20 | test.done();
21 | });
22 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "casperjs",
3 | "description": "A navigation scripting & testing utility for PhantomJS and SlimerJS",
4 | "version": "1.1.3",
5 | "keywords": [
6 | "phantomjs",
7 | "slimerjs",
8 | "test",
9 | "testing",
10 | "scraping"
11 | ],
12 | "bin": "./bin/casperjs",
13 | "author": {
14 | "name": "CasperJS Organization",
15 | "web": "https://casperjs.org/"
16 | },
17 | "bugs": {
18 | "url": "https://github.com/casperjs/casperjs/issues"
19 | },
20 | "repository": {
21 | "type": "git",
22 | "url": "git://github.com/casperjs/casperjs.git"
23 | },
24 | "licenses": [
25 | {
26 | "type": "MIT",
27 | "url": "http://www.opensource.org/licenses/mit-license.php"
28 | }
29 | ],
30 | "homepage": "http://casperjs.org"
31 | }
32 |
--------------------------------------------------------------------------------
/tests/suites/tester/setup-teardown-async.js:
--------------------------------------------------------------------------------
1 | /*eslint strict:0*/
2 |
3 | var setUp, tearDown;
4 |
5 | casper.test.setUp(function(done) {
6 | setTimeout(function() {
7 | setUp = true;
8 | done();
9 | }, 50);
10 | });
11 |
12 | casper.test.tearDown(function(done) {
13 | setTimeout(function() {
14 | tearDown = true;
15 | done();
16 | // reset
17 | casper.test.setUp();
18 | casper.test.tearDown();
19 | }, 50);
20 | });
21 |
22 | casper.test.begin('setUp() tests', 1, function(test) {
23 | test.assertTrue(setUp, 'Tester.setUp() executed the async setup function');
24 | test.done();
25 | });
26 |
27 | casper.test.begin('tearDown() tests', 1, function(test) {
28 | test.assertTrue(tearDown, 'Tester.tearDown() executed the async tear down function');
29 | test.done();
30 | });
31 |
--------------------------------------------------------------------------------
/tests/suites/casper/callutils.js:
--------------------------------------------------------------------------------
1 | /*eslint strict:0*/
2 | casper.test.begin('Casper.callUtils()', 2, function(test) {
3 | casper.start("tests/site/index.html", function(){
4 | this.evaluate(function() {
5 | /*global __utils__*/
6 | __utils__.testCallUtils = function() {
7 | return [].slice.call(arguments);
8 | };
9 | });
10 |
11 | test.assertEquals(casper.callUtils("testCallUtils", "a", "b", "c"),
12 | ["a", "b", "c"],
13 | "Casper.callUtils() invokes a client side utility");
14 |
15 | test.assertThrows(casper.callUtils, ["xxx", "a", "b", "c"],
16 | "Casper.callUtils() raises an error if used inappropriately");
17 | });
18 |
19 | casper.run(function() {
20 | test.done();
21 | });
22 | });
23 |
--------------------------------------------------------------------------------
/tests/suites/coffee.coffee:
--------------------------------------------------------------------------------
1 | "A small subset of the run.js written in coffeescript"
2 |
3 | steps = 0
4 |
5 | casper.options.onStepComplete = -> steps++
6 |
7 | casper.test.begin "writing async tests in coffeescript", 4, (test) ->
8 | casper.start "tests/site/index.html", ->
9 | test.assertTitle "CasperJS test index", "Casper.start() casper can start itself an open an url"
10 | test.assertEquals @fetchText("ul li"), "onetwothree", "Casper.fetchText() can retrieves text contents"
11 | @click "a[href=\"test.html\"]"
12 |
13 | casper.then ->
14 | test.assertTitle "CasperJS test target", "Casper.click() casper can click on a text link"
15 | @click "a[href=\"form.html\"]"
16 |
17 | casper.run ->
18 | test.assertEquals steps, 3, "Casper.options.onStepComplete() is called on step complete"
19 | @options.onStepComplete = null
20 | @test.done()
21 |
--------------------------------------------------------------------------------
/samples/metaextract.js:
--------------------------------------------------------------------------------
1 | /*eslint strict:0*/
2 | /*global CasperError, console, phantom, require*/
3 |
4 | var casper = require("casper").create();
5 | var url = casper.cli.get(0);
6 | var metas = [];
7 |
8 | if (!url) {
9 | casper
10 | .echo("Usage: $ casperjs metaextract.js ")
11 | .exit(1)
12 | ;
13 | }
14 |
15 | casper.start(url, function() {
16 | metas = this.evaluate(function() {
17 | var metas = [];
18 | [].forEach.call(document.querySelectorAll("meta"), function(elem) {
19 | var meta = {};
20 | [].slice.call(elem.attributes).forEach(function(attr) {
21 | meta[attr.name] = attr.value;
22 | });
23 | metas.push(meta);
24 | });
25 | return metas;
26 | });
27 | });
28 |
29 | casper.run(function() {
30 | require("utils").dump(metas);
31 | this.exit();
32 | });
33 |
--------------------------------------------------------------------------------
/tests/suites/casper/location.js:
--------------------------------------------------------------------------------
1 | /*eslint strict:0*/
2 | /*global CasperError, casper, console, phantom, require*/
3 | var utils = require('utils');
4 |
5 | if (utils.ltVersion(phantom.version, '1.8.0')) {
6 | // https://github.com/casperjs/casperjs/issues/101
7 | casper.warn('document.location is broken under phantomjs < 1.8');
8 | casper.test.done();
9 | } else {
10 | casper.test.begin('document.location tests', 1, function(test) {
11 | casper.start('tests/site/index.html', function() {
12 | this.evaluate(function() {
13 | document.location = '/tests/site/form.html';
14 | });
15 | });
16 | casper.then(function() {
17 | test.assertUrlMatches(/form\.html$/, 'document.location works as expected');
18 | });
19 | casper.run(function() {
20 | test.done();
21 | });
22 | });
23 | }
24 |
--------------------------------------------------------------------------------
/samples/cliplay.js:
--------------------------------------------------------------------------------
1 | /*eslint strict:0*/
2 | /*global CasperError, console, phantom, require*/
3 |
4 | var casper = require("casper").create();
5 | var dump = require("utils").dump;
6 |
7 | // removing default options passed by the Python executable
8 | casper.cli.drop("cli");
9 | casper.cli.drop("casper-path");
10 |
11 | if (casper.cli.args.length === 0 && Object.keys(casper.cli.options).length === 0) {
12 | casper
13 | .echo("Pass some args and options to see how they are handled by CasperJS")
14 | .exit(1)
15 | ;
16 | }
17 |
18 | casper.echo("Casper CLI passed args:");
19 | dump(casper.cli.args);
20 |
21 | casper.echo("Casper CLI passed options:");
22 | dump(casper.cli.options);
23 |
24 | casper.echo("Casper CLI passed RAW args:");
25 | dump(casper.cli.raw.args);
26 |
27 | casper.echo("Casper CLI passed RAW options:");
28 | dump(casper.cli.raw.options);
29 |
30 | casper.exit();
31 |
--------------------------------------------------------------------------------
/tests/suites/casper/encode.js:
--------------------------------------------------------------------------------
1 | /*eslint strict:0*/
2 | var fs = require('fs');
3 |
4 | casper.test.begin('base64encode() and download() tests', 2, function(test) {
5 | // FIXME: https://github.com/ariya/phantomjs/pull/364 has been merged, update scheme
6 | casper.start('file://' + phantom.casperPath + '/tests/site/index.html', function() {
7 | var imageUrl = 'file://' + phantom.casperPath + '/tests/site/images/phantom.png',
8 | image = this.base64encode(imageUrl);
9 | test.assertEquals(image.length, 6160, 'Casper.base64encode() can retrieve base64 contents');
10 | this.download(imageUrl, '__test_logo.png');
11 | test.assert(fs.exists('__test_logo.png'), 'Casper.download() downloads a file');
12 | if (fs.exists('__test_logo.png')) {
13 | fs.remove('__test_logo.png');
14 | }
15 | }).run(function() {
16 | test.done();
17 | });
18 | });
19 |
--------------------------------------------------------------------------------
/tests/suites/casper/onerror.js:
--------------------------------------------------------------------------------
1 | /*eslint strict:0*/
2 | casper.test.begin('page.error event tests', 2, function(test) {
3 | var error = {};
4 | var expectedMessage;
5 | if (phantom.casperEngine === 'phantomjs') {
6 | expectedMessage = "ReferenceError: Can't find variable: plop";
7 | }
8 | else {
9 | expectedMessage = "ReferenceError: plop is not defined";
10 | }
11 | casper.once("page.error", function onError(msg, trace) {
12 | error.msg = msg;
13 | error.trace = trace;
14 | });
15 | casper.start('tests/site/error.html', function() {
16 | test.assertEquals(error.msg, expectedMessage,
17 | "page.error event has been caught OK");
18 | test.assertMatch(error.trace[0].file, /error.html/,
19 | "page.error retrieves correct stack trace");
20 | });
21 | casper.run(function() {
22 | test.done();
23 | });
24 | });
25 |
--------------------------------------------------------------------------------
/samples/translate.js:
--------------------------------------------------------------------------------
1 | /*eslint strict:0*/
2 | /*global CasperError, console, phantom, require*/
3 |
4 | /**
5 | * Translation using the Google Translate Service.
6 | *
7 | * Usage:
8 | *
9 | * $ casperjs translate.js --target=fr "hello world"
10 | * bonjour tout le monde
11 | */
12 | var system = require('system'),
13 | casper = require('casper').create(),
14 | format = require('utils').format,
15 | source = casper.cli.get('source') || 'auto',
16 | target = casper.cli.get('target'),
17 | text = casper.cli.get(0),
18 | result;
19 |
20 | if (!target) {
21 | casper.warn('The --target option is mandatory.').exit(1);
22 | }
23 |
24 | casper.start(format('http://translate.google.com/#%s/%s/%s', source, target, text), function() {
25 | this.fill('form#gt-form', {text: text});
26 | }).waitForSelector('span.hps', function() {
27 | this.echo(this.fetchText("#result_box"));
28 | });
29 |
30 | casper.run();
31 |
--------------------------------------------------------------------------------
/tests/suites/casper/history.js:
--------------------------------------------------------------------------------
1 | /*eslint strict:0*/
2 | casper.test.begin('handling navigation history', 4, function(test) {
3 | casper.start('tests/site/page1.html');
4 | casper.thenOpen('tests/site/page2.html');
5 | casper.thenOpen('tests/site/page3.html');
6 | casper.back();
7 | casper.then(function() {
8 | test.assertMatch(this.getCurrentUrl(), /page2\.html$/,
9 | 'Casper.back() can go back an history step');
10 | });
11 | casper.forward();
12 | casper.then(function() {
13 | test.assertMatch(this.getCurrentUrl(), /page3\.html$/,
14 | 'Casper.forward() can go forward an history step');
15 | });
16 | casper.run(function() {
17 | test.assert(this.history.length > 0, 'Casper.history contains urls');
18 | test.assertMatch(this.history[0], /page1\.html$/,
19 | 'Casper.history has the correct first url');
20 | test.done();
21 | });
22 | });
23 |
--------------------------------------------------------------------------------
/samples/timeout.coffee:
--------------------------------------------------------------------------------
1 | ###
2 | Just a silly game.
3 |
4 | $ casperjs samples/timeout.js 500
5 | Will google.com load in less than 500ms?
6 | NOPE.
7 |
8 | $ casperjs samples/timeout.js 1000
9 | Will google.com load in less than 1000ms?
10 | NOPE.
11 |
12 | $ casperjs samples/timeout.js 1500
13 | Will google.com load in less than 1500ms?
14 | NOPE.
15 |
16 | $ casperjs samples/timeout.js 2000
17 | Will google.com load in less than 2000ms?
18 | YES!
19 | ###
20 |
21 | casper = require("casper").create
22 | onTimeout: ->
23 | @echo "NOPE.", "RED_BAR"
24 | @exit()
25 |
26 | timeout = ~~casper.cli.get 0
27 | if timeout < 1
28 | casper
29 | .echo("You must pass a valid timeout value")
30 | .exit(1)
31 |
32 | casper.echo "Will google.com load in less than #{timeout}ms?"
33 | casper.options.timeout = timeout
34 |
35 | casper.start "http://www.google.com/", ->
36 | @echo "YES!", "GREEN_BAR"
37 | @exit()
38 |
39 | casper.run()
--------------------------------------------------------------------------------
/samples/screenshot.coffee:
--------------------------------------------------------------------------------
1 | ###
2 | This script will capture a screenshot of a twitter account page
3 | Usage: $ casperjs screenshot.coffee
4 | ###
5 |
6 | casper = require("casper").create
7 | viewportSize:
8 | width: 1024
9 | height: 768
10 |
11 | twitterAccount = casper.cli.get 0
12 | filename = casper.cli.get 1
13 |
14 | if not twitterAccount or not filename or not /\.(png|jpg|pdf)$/i.test filename
15 | casper
16 | .echo("Usage: $ casperjs screenshot.coffee ")
17 | .exit(1)
18 |
19 | casper.start "https://twitter.com/#{twitterAccount}", ->
20 | @waitForSelector ".stream-container", (->
21 | @captureSelector filename, "html"
22 | @echo "Saved screenshot of #{@getCurrentUrl()} to #{filename}"
23 | ), (->
24 | @die("Timeout reached. Fail whale?")
25 | @exit()
26 | ), 12000
27 |
28 | casper.run()
29 |
--------------------------------------------------------------------------------
/tests/suites/casper/visible.js:
--------------------------------------------------------------------------------
1 | /*eslint strict:0*/
2 | casper.test.begin('visibility tests', 5, function(test) {
3 | casper.start('tests/site/visible.html', function() {
4 | test.assert(!this.visible('#img1'), 'Casper.visible() can detect if an element is invisible');
5 | test.assert(this.visible('#img2'), 'Casper.visible() can detect if an element is visible');
6 | test.assert(!this.visible('#img3'), 'Casper.visible() can detect if an element is invisible');
7 | test.assert(this.visible('img'), 'Casper.visible() can detect if an element is visible');
8 | this.waitWhileVisible('#img1', function() {
9 | test.pass('Casper.waitWhileVisible() can wait while an element is visible');
10 | }, function() {
11 | test.fail('Casper.waitWhileVisible() can wait while an element is visible');
12 | }, 2000);
13 | });
14 |
15 | casper.run(function() {
16 | test.done();
17 | });
18 | });
19 |
--------------------------------------------------------------------------------
/tests/site/waitFor.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | waitFor test
6 |
7 |
8 |
9 |
10 | one
11 | two
12 | three
13 |
14 |
15 | Loading...
16 |
17 | Voilà
18 | I'm hidden.
19 | I'm visible.
20 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/samples/events.coffee:
--------------------------------------------------------------------------------
1 | ###
2 | This script will add a custom HTTP status code handler, here for 404 pages.
3 | ###
4 |
5 | casper = require("casper").create()
6 |
7 | casper.on "http.status.200", (resource) ->
8 | @echo "#{resource.url} is OK", "INFO"
9 |
10 | casper.on "http.status.301", (resource) ->
11 | @echo "#{resource.url} is permanently redirected", "PARAMETER"
12 |
13 | casper.on "http.status.302", (resource) ->
14 | @echo "#{resource.url} is temporarily redirected", "PARAMETER"
15 |
16 | casper.on "http.status.404", (resource) ->
17 | @echo "#{resource.url} is not found", "COMMENT"
18 |
19 | casper.on "http.status.500", (resource) ->
20 | @echo "#{resource.url} is in error", "ERROR"
21 |
22 | links = [
23 | "http://google.com/"
24 | "http://www.google.com/"
25 | "http://www.google.com/plop"
26 | ]
27 |
28 | casper.start()
29 |
30 | casper.each links, (self, link) ->
31 | self.thenOpen link, ->
32 | @echo "#{link} loaded"
33 |
34 | casper.run()
35 |
--------------------------------------------------------------------------------
/tests/suites/casper/agent.js:
--------------------------------------------------------------------------------
1 | /*eslint strict:0*/
2 | function testUA(ua, match) {
3 | casper.test.assertMatch(
4 | ua, match, 'Default user agent matches ' + match
5 | );
6 | }
7 |
8 | function fetchUA(requestData, request) {
9 | var headers = requestData.headers.filter(function(header) {
10 | return header.name === "User-Agent";
11 | });
12 | casper.test.assert(headers.length > 0);
13 | testUA(headers.pop().value, /plop/);
14 | }
15 |
16 | casper.test.begin('userAgent() tests', 3, {
17 | originalUA: casper.options.pageSettings.userAgent,
18 |
19 | tearDown: function(test) {
20 | casper.userAgent(this.originalUA);
21 | },
22 |
23 | test: function(test) {
24 | testUA(casper.options.pageSettings.userAgent, /CasperJS/);
25 | casper.start().userAgent('plop').once('resource.requested', fetchUA);
26 | casper.thenOpen('tests/site/index.html').run(function() {
27 | test.done();
28 | });
29 | }
30 | });
31 |
32 |
--------------------------------------------------------------------------------
/samples/extends.js:
--------------------------------------------------------------------------------
1 | /*eslint strict:0*/
2 | /*global CasperError, console, phantom, require*/
3 |
4 | var casper = require("casper").create({
5 | loadImages: false,
6 | logLevel: "debug",
7 | verbose: true
8 | });
9 |
10 | var links = {
11 | "http://edition.cnn.com/": 0,
12 | "http://www.nytimes.com/": 0,
13 | "http://www.bbc.co.uk/": 0,
14 | "http://www.guardian.co.uk/": 0
15 | };
16 |
17 | var fantomas = Object.create(casper);
18 |
19 | fantomas.countLinks = function() {
20 | return this.evaluate(function() {
21 | return __utils__.findAll("a[href]").length;
22 | });
23 | };
24 |
25 | fantomas.renderJSON = function(what) {
26 | this.echo(JSON.stringify(what, null, " "));
27 | };
28 |
29 | fantomas.start();
30 |
31 | Object.keys(links).forEach(function(url) {
32 | fantomas.thenOpen(url, function() {
33 | links[url] = this.countLinks();
34 | });
35 | });
36 |
37 | fantomas.run(function() {
38 | this.renderJSON(links);
39 | this.exit();
40 | });
41 |
--------------------------------------------------------------------------------
/samples/googlelinks.coffee:
--------------------------------------------------------------------------------
1 | links = []
2 | casper = require("casper").create()
3 |
4 | getLinks = ->
5 | links = document.querySelectorAll("h3.r a")
6 | Array::map.call links, (e) ->
7 | try
8 | (/url\?q=(.*)&sa=U/).exec(e.getAttribute("href"))[1]
9 | catch e
10 | e.getAttribute "href"
11 |
12 | casper.start "http://google.fr/", ->
13 | # search for 'casperjs' from google form
14 | @fill "form[action=\"/search\"]", q: "casperjs", true
15 |
16 | casper.then ->
17 | # aggregate results for the 'casperjs' search
18 | links = @evaluate(getLinks)
19 | # now search for 'phantomjs' by fillin the form again
20 | @fill "form[action=\"/search\"]", q: "phantomjs", true
21 |
22 | casper.then ->
23 | # aggregate results for the 'phantomjs' search
24 | links = links.concat(@evaluate(getLinks))
25 |
26 | casper.run ->
27 | # echo results in some pretty fashion
28 | @echo links.length + " links found:"
29 | @echo " - " + links.join("\n - ")
30 | @exit()
31 |
--------------------------------------------------------------------------------
/tests/suites/casper/newpage.js:
--------------------------------------------------------------------------------
1 | /*global casper*/
2 | /*jshint strict:false*/
3 | casper.test.begin('newPage() tests', 5, function(test) {
4 | casper.start('tests/site/index.html', function() {
5 | test.assertTitle('CasperJS test index', 'Casper.start() opened the first page');
6 | test.assertEval(function() {
7 | return typeof(__utils__) === "object";
8 | }, 'Casper.start() injects ClientUtils instance within remote DOM');
9 | }).then(function(){
10 | casper.newPage();
11 | casper.thenOpen('tests/site/page1.html', function(){
12 | test.assertTitle('CasperJS test page 1', 'casper.newPage() created a new page object');
13 | test.assertEval(function() {
14 | return typeof(__utils__) === "object";
15 | }, 'Casper.newPage() injects ClientUtils instance within remote DOM');
16 | });
17 | }).run(function() {
18 | test.done();
19 | });
20 | test.assert(casper.started, 'Casper.start() started');
21 | });
22 |
--------------------------------------------------------------------------------
/samples/multirun.coffee:
--------------------------------------------------------------------------------
1 | casper = require("casper").create verbose: true
2 |
3 | countLinks = ->
4 | document.querySelectorAll('a').length
5 |
6 | suites = [
7 | ->
8 | @echo "Suite 1"
9 | @start "http://google.com/", -> @echo "Page title: #{@getTitle()}"
10 | @then -> @echo "#{@evaluate(countLinks)} links"
11 | ->
12 | @echo "Suite 2"
13 | @start "http://yahoo.com/", -> @echo "Page title: #{@getTitle()}"
14 | @then -> @echo "#{@evaluate(countLinks)} links"
15 | ->
16 | @echo "Suite 3"
17 | @start "http://bing.com/", -> @echo "Page title: #{@getTitle()}"
18 | @then -> @echo "#{@evaluate(countLinks)} links"
19 | ]
20 |
21 | casper.start()
22 |
23 | casper.then ->
24 | @echo("Starting")
25 |
26 | currentSuite = 0;
27 |
28 | check = ->
29 | if suites[currentSuite]
30 | suites[currentSuite].call @
31 | currentSuite++;
32 | casper.run check
33 | else
34 | @echo "All done."
35 | @exit()
36 |
37 | casper.run check
38 |
--------------------------------------------------------------------------------
/samples/steptimeout.coffee:
--------------------------------------------------------------------------------
1 | failed = []
2 | start = null
3 | links = [
4 | "http://google.com/"
5 | "http://akei.com/"
6 | "http://lemonde.fr/"
7 | "http://liberation.fr/"
8 | "http://cdiscount.fr/"
9 | ]
10 |
11 | casper = require("casper").create
12 | onStepTimeout: ->
13 | failed.push @requestUrl
14 | @test.fail "#{@requestUrl} loads in less than #{timeout}ms."
15 |
16 | casper.on "load.finished", ->
17 | @echo "#{@requestUrl} loaded in #{new Date() - start}ms", "PARAMETER"
18 |
19 | timeout = ~~casper.cli.get(0)
20 | timeout = 1000 if timeout < 1
21 | casper.options.stepTimeout = timeout
22 |
23 | casper.echo "Testing with timeout=#{timeout}ms, please be patient."
24 |
25 | casper.start()
26 |
27 | casper.each links, (self, link) ->
28 | @then ->
29 | @test.comment "Loading #{link}"
30 | start = new Date()
31 | @open link
32 | @then ->
33 | if @requestUrl not in failed
34 | @test.pass "#{@requestUrl} loaded in less than #{timeout}ms."
35 |
36 | casper.run ->
37 | @test.renderResults true
38 |
--------------------------------------------------------------------------------
/samples/customlogging.coffee:
--------------------------------------------------------------------------------
1 | ###
2 | A basic custom logging implementation. The idea is to (extremely) verbosely
3 | log every received resource.
4 | ###
5 | casper = require("casper").create
6 | verbose: true # we want to see the log printed out to the console
7 | logLevel: "verbose" # of course we want to see logs to our new level :)
8 |
9 | ###
10 | Every time a resource is received, a new log entry is added to the stack
11 | at the 'verbose' level.
12 | ###
13 | casper.on 'resource.received', (resource) ->
14 | infos = []
15 | props = [
16 | "url"
17 | "status"
18 | "statusText"
19 | "redirectURL"
20 | "bodySize"
21 | ]
22 | infos.push resource[prop] for prop in props
23 | infos.push "[#{header.name}: #{header.value}]" for header in resource.headers
24 | @log infos.join(", "), "verbose"
25 |
26 | # add a new 'verbose' logging level at the lowest priority
27 | casper.logLevels = ["verbose"].concat casper.logLevels
28 |
29 | # test our new logger with google
30 | casper.start("http://www.google.com/").run ->
31 | @exit()
32 |
--------------------------------------------------------------------------------
/tests/suites/casper/auth.js:
--------------------------------------------------------------------------------
1 | /*eslint strict:0, max-statements:0*/
2 |
3 | casper.test.begin('HTTP authentication tests', 8, function(test) {
4 | casper.start('tests/site/index.html');
5 |
6 | casper.configureHttpAuth('http://localhost/');
7 | test.assertEquals(casper.page.settings.userName, undefined);
8 | test.assertEquals(casper.page.settings.password, undefined);
9 |
10 | casper.configureHttpAuth('http://niko:plop@localhost/');
11 | test.assertEquals(casper.page.settings.userName, 'niko');
12 | test.assertEquals(casper.page.settings.password, 'plop');
13 |
14 | casper.configureHttpAuth('http://localhost/', {username: 'john', password: 'doe'});
15 | test.assertEquals(casper.page.settings.userName, 'john');
16 | test.assertEquals(casper.page.settings.password, 'doe');
17 |
18 | casper.configureHttpAuth('http://niko:plop@localhost/', {username: 'john', password: 'doe'});
19 | test.assertEquals(casper.page.settings.userName, 'niko');
20 | test.assertEquals(casper.page.settings.password, 'plop');
21 |
22 | casper.run(function() {
23 | test.done();
24 | });
25 | });
26 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | Copyright (c) 2011-2015 Nicolas Perriault
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to deal
5 | in the Software without restriction, including without limitation the rights
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | copies of the Software, and to permit persons to whom the Software is furnished
8 | to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in all
11 | copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | THE SOFTWARE.
20 |
--------------------------------------------------------------------------------
/tests/suites/casper/scroll.js:
--------------------------------------------------------------------------------
1 | /*eslint strict:0*/
2 | casper.test.begin('Casper.scrollTo()', 2, function(test) {
3 | casper.start().then(function() {
4 | this.setContent('large div is large
');
5 | this.scrollTo(1000, 1000);
6 | test.assertEquals(this.getGlobal("scrollX"), 1000, "scrollTo() scrolls to X position");
7 | test.assertEquals(this.getGlobal("scrollY"), 1000, "scrollTo() scrolls to Y position");
8 | });
9 |
10 | casper.run(function() {
11 | test.done();
12 | });
13 | });
14 |
15 |
16 | casper.test.begin('Casper.scrollToBottom()', 1, function(test) {
17 | casper.start().then(function() {
18 | this.setContent('long div is long
');
19 | this.scrollToBottom();
20 | test.assertEval(function() {
21 | /*global __utils__*/
22 | return __utils__.getDocumentHeight() - window.innerHeight === window.scrollY;
23 | }, "scrollToBottom() scrolls to max Y by default");
24 | });
25 |
26 | casper.run(function() {
27 | test.done();
28 | });
29 | });
30 |
--------------------------------------------------------------------------------
/tests/suites/casper/elementattribute.js:
--------------------------------------------------------------------------------
1 | /*eslint strict:0*/
2 | var x = require('casper').selectXPath;
3 |
4 | casper.test.begin('getElementAttribute() tests', 4, function(test) {
5 | casper.start('tests/site/elementattribute.html', function() {
6 | test.assertEquals(this.getElementAttribute('.testo', 'data-stuff'),
7 | 'beautiful string', 'Casper.getElementAttribute() works with a CSS selector');
8 | test.assertEquals(this.getElementAttribute(x('//div[@class]'), 'data-stuff'),
9 | 'beautiful string', 'Casper.getElementAttribute() works with a XPath selector');
10 | }).then(function() {
11 | test.assertEquals(this.getElementsAttribute('.testo', 'data-stuff'),
12 | ['beautiful string', 'not as beautiful string'],
13 | 'Casper.getElementsAttribute() works with a CSS selector');
14 | test.assertEquals(this.getElementsAttribute(x('//div[@class]'), 'data-stuff'),
15 | ['beautiful string', 'not as beautiful string'],
16 | 'Casper.getElementsAttribute() works with a XPath selector');
17 | }).run(function() {
18 | test.done();
19 | });
20 | });
21 |
--------------------------------------------------------------------------------
/samples/screenshot.js:
--------------------------------------------------------------------------------
1 | /*eslint strict:0*/
2 | /*global CasperError, console, phantom, require*/
3 |
4 | /**
5 | * This script will capture a screenshot of a twitter account page
6 | * Usage: $ casperjs screenshot.js
7 | */
8 |
9 | var casper = require("casper").create({
10 | viewportSize: {
11 | width: 1024,
12 | height: 768
13 | }
14 | });
15 |
16 | var twitterAccount = casper.cli.get(0);
17 | var filename = casper.cli.get(1);
18 |
19 | if (!twitterAccount || !filename || !/\.(png|jpg|pdf)$/i.test(filename)) {
20 | casper
21 | .echo("Usage: $ casperjs screenshot.js ")
22 | .exit(1)
23 | ;
24 | }
25 |
26 | casper.start("https://twitter.com/" + twitterAccount, function() {
27 | this.waitForSelector(".stream-container", (function() {
28 | this.captureSelector(filename, "html");
29 | this.echo("Saved screenshot of " + (this.getCurrentUrl()) + " to " + filename);
30 | }), (function() {
31 | this.die("Timeout reached. Fail whale?");
32 | this.exit();
33 | }), 12000);
34 | });
35 |
36 | casper.run();
37 |
--------------------------------------------------------------------------------
/samples/googletesting.coffee:
--------------------------------------------------------------------------------
1 | # Google sample testing.
2 | #
3 | # Usage:
4 | # $ casperjs test googletesting.coffee
5 | casper.test.begin 'Google search retrieves 10 or more results', 5, (test) ->
6 | casper.start "http://www.google.fr/", ->
7 | test.assertTitle "Google", "google homepage title is the one expected"
8 | test.assertExists 'form[action="/search"]', "main form is found"
9 | @fill 'form[action="/search"]', q: "foo", true
10 |
11 | casper.then ->
12 | test.assertTitle "foo - Recherche Google", "google title is ok"
13 | test.assertUrlMatch /q=foo/, "search term has been submitted"
14 | test.assertEval (->
15 | __utils__.findAll("h3.r").length >= 10
16 | ), "google search for \"foo\" retrieves 10 or more results"
17 |
18 | casper.run -> test.done()
19 |
20 | casper.test.begin "Casperjs.org is first ranked", 1, (test) ->
21 | casper.start "http://www.google.fr/", ->
22 | @fill "form[action=\"/search\"]", q: "casperjs", true
23 |
24 | casper.then ->
25 | test.assertSelectorContains ".g", "casperjs.org", "casperjs.org is first ranked"
26 |
27 | casper.run -> test.done()
28 |
29 |
--------------------------------------------------------------------------------
/tests/suites/pagestack.js:
--------------------------------------------------------------------------------
1 | /*eslint strict:0, max-statements:0*/
2 | var pagestack = require('pagestack');
3 | var utils = require('utils');
4 | var webpage = require('webpage');
5 |
6 | casper.test.begin('pagestack module tests', 14, function(test) {
7 | var stack = pagestack.create();
8 | var page1 = webpage.create();
9 | page1.url = 'page1.html';
10 | stack.push(page1);
11 | test.assertEquals(stack.length, 1);
12 | test.assert(utils.isWebPage(stack[0]));
13 | test.assertEquals(stack[0], page1);
14 | test.assertEquals(stack.list().length, 1);
15 | test.assertEquals(stack.list()[0], page1.url);
16 |
17 | var page2 = webpage.create();
18 | page2.url = 'page2.html';
19 | stack.push(page2);
20 | test.assertEquals(stack.length, 2);
21 | test.assert(utils.isWebPage(stack[1]));
22 | test.assertEquals(stack[1], page2);
23 | test.assertEquals(stack.list().length, 2);
24 | test.assertEquals(stack.list()[1], page2.url);
25 |
26 | test.assertEquals(stack.clean(), 1);
27 | test.assertEquals(stack[0], page2);
28 | test.assertEquals(stack.list().length, 1);
29 | test.assertEquals(stack.list()[0], page2.url);
30 |
31 | test.done();
32 | });
33 |
--------------------------------------------------------------------------------
/samples/events.js:
--------------------------------------------------------------------------------
1 | /*eslint strict:0*/
2 | /*global CasperError, console, phantom, require*/
3 |
4 | /**
5 | * This script will add a custom HTTP status code handler, here for 404 pages.
6 | */
7 | var casper = require("casper").create();
8 |
9 | casper.on("http.status.200", function(resource) {
10 | this.echo(resource.url + " is OK", "INFO");
11 | });
12 |
13 | casper.on("http.status.301", function(resource) {
14 | this.echo(resource.url + " is permanently redirected", "PARAMETER");
15 | });
16 |
17 | casper.on("http.status.302", function(resource) {
18 | this.echo(resource.url + " is temporarily redirected", "PARAMETER");
19 | });
20 |
21 | casper.on("http.status.404", function(resource) {
22 | this.echo(resource.url + " is not found", "COMMENT");
23 | });
24 |
25 | casper.on("http.status.500", function(resource) {
26 | this.echo(resource.url + " is in error", "ERROR");
27 | });
28 |
29 | var links = [
30 | "http://google.com/",
31 | "http://www.google.com/",
32 | "http://www.google.com/plop"
33 | ];
34 |
35 | casper.start();
36 |
37 | casper.each(links, function(self, link) {
38 | self.thenOpen(link, function() {
39 | this.echo(link + " loaded");
40 | });
41 | });
42 |
43 | casper.run();
44 |
--------------------------------------------------------------------------------
/samples/timeout.js:
--------------------------------------------------------------------------------
1 | /*eslint strict:0*/
2 | /*global CasperError, console, phantom, require*/
3 |
4 | /**
5 | * Just a silly game.
6 | *
7 | * $ casperjs samples/timeout.js 500
8 | * Will google.com load in less than 500ms?
9 | * NOPE.
10 | *
11 | * $ casperjs samples/timeout.js 1000
12 | * Will google.com load in less than 1000ms?
13 | * NOPE.
14 | *
15 | * $ casperjs samples/timeout.js 1500
16 | * Will google.com load in less than 1500ms?
17 | * NOPE.
18 | *
19 | * $ casperjs samples/timeout.js 2000
20 | * Will google.com load in less than 2000ms?
21 | * YES!
22 | */
23 |
24 | var casper = require("casper").create({
25 | onTimeout: function() {
26 | this
27 | .echo("NOPE.", "RED_BAR")
28 | .exit()
29 | ;
30 | }
31 | });
32 |
33 | var timeout = ~~casper.cli.get(0);
34 |
35 | if (timeout < 1) {
36 | casper
37 | .echo("You must pass a valid timeout value")
38 | .exit(1)
39 | ;
40 | }
41 |
42 | casper.echo("Will google.com load in less than " + timeout + "ms?");
43 | casper.options.timeout = timeout;
44 |
45 | casper.start("http://www.google.com/", function() {
46 | this.echo("YES!", "GREEN_BAR");
47 | this.exit();
48 | });
49 |
50 | casper.run();
51 |
--------------------------------------------------------------------------------
/samples/customlogging.js:
--------------------------------------------------------------------------------
1 | /*eslint strict:0*/
2 | /*global CasperError, console, phantom, require*/
3 |
4 | /**
5 | * A basic custom logging implementation. The idea is to (extremely) verbosely
6 | * log every received resource.
7 | */
8 | var casper = require("casper").create({
9 | verbose: true,
10 | logLevel: "verbose"
11 | });
12 |
13 | /**
14 | * Every time a resource is received, a new log entry is added to the stack at
15 | * the 'verbose' level.
16 | */
17 | casper.on('resource.received', function(resource) {
18 | var infos = [];
19 | var props = [
20 | "url",
21 | "status",
22 | "statusText",
23 | "redirectURL",
24 | "bodySize"
25 | ];
26 | props.forEach(function(prop) {
27 | infos.push(resource[prop]);
28 | });
29 | resource.headers.forEach(function(header) {
30 | infos.push("[" + header.name + ": " + header.value + "]");
31 | });
32 | this.log(infos.join(", "), "verbose");
33 | });
34 |
35 | // add a new 'verbose' logging level at the lowest priority
36 | casper.logLevels = ["verbose"].concat(casper.logLevels);
37 |
38 | // test our new logger with google
39 | casper.start("http://www.google.com/").run(function() {
40 | this.exit();
41 | });
42 |
--------------------------------------------------------------------------------
/tests/suites/casper/alert.js:
--------------------------------------------------------------------------------
1 | /*eslint strict:0*/
2 | casper.test.begin('alert events', 1, {
3 | ok: false,
4 |
5 | tearDown: function(test) {
6 | casper.removeAllListeners('remote.alert');
7 | },
8 |
9 | test: function(test) {
10 | var self = this;
11 |
12 | casper.once('remote.alert', function(message) {
13 | self.ok = (message === 'plop');
14 | });
15 |
16 | casper.start('tests/site/alert.html', function() {
17 | test.assert(self.ok, 'alert event has been intercepted');
18 | });
19 |
20 | casper.run(function() {
21 | test.done();
22 | });
23 | }
24 | });
25 |
26 | casper.test.begin("Casper.waitForAlert() waits for an alert", 1, function(test) {
27 | casper.start().then(function() {
28 | this.evaluate(function() {
29 | setTimeout(function() {
30 | alert("plop");
31 | }, 500);
32 | });
33 | });
34 |
35 | casper.waitForAlert(function(response) {
36 | test.assertEquals(response.data, "plop",
37 | "Casper.waitForAlert() can wait for an alert to be triggered");
38 | });
39 |
40 | casper.run(function() {
41 | test.done();
42 | });
43 | });
44 |
--------------------------------------------------------------------------------
/tests/suites/casper/flow.coffee:
--------------------------------------------------------------------------------
1 | casper.test.begin 'handling waits and timeouts', 13, (test) ->
2 | step = 0
3 |
4 | casper.start "tests/site/resources.html", ->
5 | test.assertEquals ++step, 1, "step 1"
6 | @wait 400, ->
7 | test.assertEquals ++step, 2, "step 1.1"
8 | @wait 200, ->
9 | test.assertEquals ++step, 3, "step 1.1.1"
10 | @wait 200, ->
11 | test.assertEquals ++step, 4, "step 1.1.1.1"
12 | @then ->
13 | test.assertEquals ++step, 5, "step 1.1.2.1"
14 | @wait 400, ->
15 | test.assertEquals ++step, 6, "step 1.2"
16 |
17 | casper.wait 200, ->
18 | test.assertEquals ++step, 7, "step 2"
19 |
20 | casper.waitForSelector(
21 | '#noneExistingSelector'
22 | -> test.fail "should run into timeout"
23 | -> test.assertEquals ++step, 8, "step 3 sucessfully timed out"
24 | 1000
25 | )
26 | casper.then ->
27 | test.assertEquals ++step, 9, "step 4"
28 | @wait 300, ->
29 | test.assertEquals ++step, 10, "step 4.1"
30 | @wait 300, ->
31 | test.assertEquals ++step, 11, "step 4.1.1"
32 | @wait 100, ->
33 | test.assertEquals ++step, 12, "step 5.2"
34 |
35 | casper.then ->
36 | test.assertEquals ++step, 13, "last step"
37 |
38 | casper.run(-> test.done())
39 |
--------------------------------------------------------------------------------
/casperjs.gemspec:
--------------------------------------------------------------------------------
1 | # by hannyu
2 |
3 | CASPERJS_VERSION = File.read("package.json")[/version.*:.*"(.*?)"/,1].gsub(/[\-_\+]/,".")
4 |
5 | Gem::Specification.new do |s|
6 | s.name = "casperjs"
7 | s.version = CASPERJS_VERSION
8 | s.homepage = "http://casperjs.org/"
9 | s.authors = ["Nicolas Perriault", ]
10 | s.email = ["nperriault@gmail.com",]
11 | s.description = "CasperJS is a navigation scripting & testing utility for [PhantomJS](http://www.phantomjs.org/).
12 | It eases the process of defining a full navigation scenario and provides useful
13 | high-level functions, methods & syntaxic sugar for doing common tasks."
14 | s.summary = "Navigation scripting & testing utility for PhantomJS"
15 | s.extra_rdoc_files = ["LICENSE.md", "README.md"]
16 | s.files = Dir["LICENSE.md", "README.md", "CHANGELOG.md", "package.json", "casperjs.gemspec",
17 | "bin/bootstrap.js", "bin/usage.txt", "bin/casperjs_python",
18 | "docs/**/*", "modules/**/*", "samples/**/*", "tests/**/*"]
19 | s.bindir = "rubybin"
20 | s.executables = [ "casperjs" ]
21 | s.license = "MIT"
22 | s.requirements = [ "PhantomJS v1.7" ]
23 | end
24 |
--------------------------------------------------------------------------------
/tests/suites/fs.js:
--------------------------------------------------------------------------------
1 | /*eslint strict:0*/
2 | var fs = require('fs');
3 |
4 | casper.test.begin('fs.dirname() tests', 8, function(test) {
5 | var tests = {
6 | '/local/plop/foo.js': '/local/plop',
7 | 'local/plop/foo.js': 'local/plop',
8 | './local/plop/foo.js': './local/plop',
9 | 'c:\\local\\plop\\foo.js': 'c:/local/plop',
10 | 'D:\\local\\plop\\foo.js': 'D:/local/plop',
11 | 'D:\\local\\plop\\': 'D:/local/plop',
12 | 'c:\\': 'c:',
13 | 'c:': 'c:'
14 | };
15 | for (var testCase in tests) {
16 | test.assertEquals(fs.dirname(testCase), tests[testCase], 'fs.dirname() does its job for ' + testCase);
17 | }
18 | test.done();
19 | });
20 |
21 | casper.test.begin('fs.isWindows() tests', 6, function(test) {
22 | var tests = {
23 | '/': false,
24 | '/local/plop/foo.js': false,
25 | 'D:\\local\\plop\\': true,
26 | 'c:\\': true,
27 | 'c:': true,
28 | '\\\\Server\\Plop': true
29 | };
30 | for (var testCase in tests) {
31 | test.assertEquals(fs.isWindows(testCase), tests[testCase], 'fs.isWindows() does its job for ' + testCase);
32 | }
33 | test.done();
34 | });
35 |
--------------------------------------------------------------------------------
/samples/googlepagination.coffee:
--------------------------------------------------------------------------------
1 | ###
2 | Capture multiple pages of google search results
3 |
4 | Usage: $ casperjs googlepagination.coffee my search terms
5 |
6 | (all arguments will be used as the query)
7 | ###
8 |
9 | casper = require("casper").create(
10 | waitTimeout: 1000
11 | pageSettings:
12 | userAgent: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:23.0) Gecko/20130404 Firefox/23.0"
13 | )
14 | currentPage = 1
15 |
16 | if casper.cli.args.length is 0
17 | casper
18 | .echo("Usage: $ casperjs googlepagination.coffee my search terms")
19 | .exit(1)
20 |
21 | terminate = ->
22 | @echo("that's all, folks.").exit();
23 |
24 | processPage = ->
25 | @echo "capturing page #{currentPage}"
26 | @capture "google-results-p#{currentPage}.png"
27 |
28 | # don't go too far down the rabbit hole
29 | if currentPage >= 5 || !@exists "#pnnext"
30 | return terminate.call casper
31 |
32 | currentPage++
33 | @echo "requesting next page: #{currentPage}"
34 | url = @getCurrentUrl()
35 | @thenClick("#pnnext").then ->
36 | @waitFor (->
37 | url isnt @getCurrentUrl()
38 | ), processPage, terminate
39 |
40 | casper.start "http://google.fr/", ->
41 | @fill 'form[action="/search"]', q: casper.cli.args.join(" "), true
42 |
43 | casper.waitForSelector "#pnnext", processPage, terminate
44 |
45 | casper.run()
46 |
--------------------------------------------------------------------------------
/tests/suites/casper/headers.js:
--------------------------------------------------------------------------------
1 | /*eslint strict:0*/
2 | var server = require('webserver').create();
3 | var service = server.listen(8090, function(request, response) {
4 | response.statusCode = 200;
5 | response.headers = {
6 | 'Content-Language': 'en',
7 | 'Content-Type': 'text/html',
8 | 'Date': new Date().toUTCString()
9 | };
10 | response.write("ok");
11 | response.close();
12 | });
13 |
14 | casper.test.begin('Casper.headers.get() using file protocol', 1, function(test) {
15 | casper.start('file://' + phantom.casperPath + 'tests/site/index.html', function(response) {
16 | test.assertEquals(response, {data: null}, 'Empty http response on local page');
17 | }).run(function() {
18 | test.done();
19 | });
20 | });
21 |
22 | casper.test.begin('Casper.headers.get() using http protocol', 3, function(test) {
23 | casper.start('http://localhost:8090/', function(response) {
24 | var headers = response.headers;
25 | test.assertEquals(headers.get('Content-Language'), 'en', 'Checking existing header (case sensitive)');
26 | test.assertEquals(headers.get('content-language'), 'en', 'Checking existing header (case insensitive)');
27 | test.assertEquals(headers.get('X-Is-Troll'), null, 'Checking unexisting header');
28 | }).run(function() {
29 | server.close();
30 | test.done();
31 | });
32 | });
33 |
--------------------------------------------------------------------------------
/samples/googlelinks.js:
--------------------------------------------------------------------------------
1 | /*eslint strict:0*/
2 | /*global CasperError, console, phantom, require*/
3 |
4 | var links = [];
5 | var casper = require("casper").create();
6 |
7 | function getLinks() {
8 | var links = document.querySelectorAll("h3.r a");
9 | return Array.prototype.map.call(links, function(e) {
10 | try {
11 | // google handles redirects hrefs to some script of theirs
12 | return (/url\?q=(.*)&sa=U/).exec(e.getAttribute("href"))[1];
13 | } catch (err) {
14 | return e.getAttribute("href");
15 | }
16 | });
17 | }
18 |
19 | casper.start("http://google.fr/", function() {
20 | // search for 'casperjs' from google form
21 | this.fill('form[action="/search"]', { q: "casperjs" }, true);
22 | });
23 |
24 | casper.then(function() {
25 | // aggregate results for the 'casperjs' search
26 | links = this.evaluate(getLinks);
27 | // now search for 'phantomjs' by fillin the form again
28 | this.fill('form[action="/search"]', { q: "phantomjs" }, true);
29 | });
30 |
31 | casper.then(function() {
32 | // aggregate results for the 'phantomjs' search
33 | links = links.concat(this.evaluate(getLinks));
34 | });
35 |
36 | casper.run(function() {
37 | // echo results in some pretty fashion
38 | this.echo(links.length + " links found:");
39 | this.echo(" - " + links.join("\n - "));
40 | this.exit();
41 | });
42 |
--------------------------------------------------------------------------------
/tests/suites/casper/scripts.js:
--------------------------------------------------------------------------------
1 | /*eslint strict:0*/
2 | casper.test.begin('remote script includes tests', 4, {
3 | setUp: function() {
4 | casper.options.remoteScripts = [
5 | 'includes/include1.js', // local includes are actually served
6 | 'includes/include2.js' // through the local test webserver
7 | ];
8 | },
9 |
10 | tearDown: function() {
11 | casper.options.remoteScripts = [];
12 | },
13 |
14 | test: function(test) {
15 | casper.start('tests/site/index.html', function() {
16 | test.assertSelectorHasText('#include1', 'include1',
17 | 'Casper.includeRemoteScripts() includes a first remote script on start');
18 | test.assertSelectorHasText('#include2', 'include2',
19 | 'Casper.includeRemoteScripts() includes a second remote script on start');
20 | });
21 |
22 | casper.thenOpen('tests/site/form.html', function() {
23 | test.assertSelectorHasText('#include1', 'include1',
24 | 'Casper.includeRemoteScripts() includes a first remote script on second step');
25 | test.assertSelectorHasText('#include2', 'include2',
26 | 'Casper.includeRemoteScripts() includes a second remote script on second step');
27 | });
28 |
29 | casper.run(function() {
30 | test.done();
31 | });
32 | }
33 | });
34 |
--------------------------------------------------------------------------------
/tests/suites/tester/begin-config.js:
--------------------------------------------------------------------------------
1 | /*eslint strict:0, eqeqeq:0*/
2 | var steps = [];
3 |
4 | casper.test.begin('Tester.begin() configuration', 10, {
5 | fixtures: [1, 2, 3],
6 |
7 | _this: function() {
8 | return this;
9 | },
10 |
11 | setUp: function(test) {
12 | steps.push('setUp');
13 | test.pass('config.setUp() has been called');
14 | test.assert(this == this._this(), 'config.setUp() is using the expected context');
15 | test.assertEquals(this.fixtures, [1, 2, 3], 'config.setUp() accesses fixtures');
16 | },
17 |
18 | tearDown: function(test) {
19 | steps.push('tearDown');
20 | test.pass('config.tearDown() has been called');
21 | test.assert(this == this._this(), 'config.test() is using the expected context');
22 | test.assertEquals(this.fixtures, [1, 2, 3], 'config.tearDown() accesses fixtures');
23 | test.assertEquals(steps, ['setUp', 'test', 'tearDown'],
24 | 'Tester.begin() has processed the configuration in the expected order');
25 | },
26 |
27 | test: function(test) {
28 | steps.push('test');
29 | test.pass('config.test() has been called');
30 | test.assert(this == this._this(), 'config.tearDown() is using the expected context');
31 | test.assertEquals(this.fixtures, [1, 2, 3], 'config.test() accesses fixtures');
32 | test.done();
33 | }
34 | });
35 |
--------------------------------------------------------------------------------
/rpm/build:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # A little helper script to build the RPM.
4 |
5 | if [ ! -f "../package.json" ]; then
6 | echo "Execute rpm build script in rpm directory"
7 | exit 1
8 | fi
9 |
10 | name="casperjs"
11 | name=${name%.spec}
12 | topdir=$(mktemp -d "${TMPDIR:-/tmp}/${name}-build-XXXXXX")
13 | # Get version from package.json
14 | version=$(grep '"version"' ../package.json | sed 's/.*"\(.*\)": "\(.*\)".*/\2/' | sed 's/[-]//')
15 | builddir=${TMPDIR:-/tmp}/${name}-${version}
16 | sourcedir="${topdir}/SOURCES"
17 | buildroot="${topdir}/BUILD/${name}-${version}-root"
18 |
19 | mkdir -p ${topdir}/{RPMS,SRPMS,SOURCES,BUILD}
20 | mkdir -p ${buildroot} ${builddir}
21 |
22 | echo "=> Copying sources..."
23 | ( cd .. && tar cf - ./[A-Z]* ./package.json ./bin ./samples ./tests ./modules | tar xf - -C ${builddir} )
24 |
25 | echo "=> Creating source tarball under ${sourcedir}..."
26 | ( cd ${builddir}/.. && tar zcf ${sourcedir}/${name}-${version}.tar.gz ${name}-${version} )
27 |
28 | echo "=> Building RPM..."
29 | rpm=$(rpmbuild --define "_topdir ${topdir}" --define "_version ${version}" --buildroot ${buildroot} --clean -bb ${name}.spec | awk '/\/RPMS\// { print $2; }')
30 |
31 | if [ $? -ne 0 ]; then
32 | echo "Failed to build RPM package."
33 | exit 1
34 | fi
35 |
36 | echo ${rpm}
37 | cp ${rpm} ${TMPDIR:-/tmp}/
38 | rm -fr ${topdir}
39 |
40 | echo "RPM package build finished."
41 | echo ${TMPDIR:-/tmp}/${rpm##*/}
42 |
--------------------------------------------------------------------------------
/docs/license.rst:
--------------------------------------------------------------------------------
1 | .. _license:
2 |
3 | .. index:: Licensing
4 |
5 | =======
6 | License
7 | =======
8 |
9 | `CasperJS `_ is released under the terms of the
10 | `MIT license `_.
11 |
12 | ::
13 |
14 | Copyright (c) 2011-{{year}} Nicolas Perriault
15 | Permission is hereby granted, free of charge, to any person obtaining a
16 | copy of this software and associated documentation files (the "Software"),
17 | to deal in the Software without restriction, including without limitation
18 | the rights to use, copy, modify, merge, publish, distribute, sublicense,
19 | and/or sell copies of the Software, and to permit persons to whom the
20 | Software is furnished to do so, subject to the following conditions:
21 | The above copyright notice and this permission notice shall be included
22 | in all copies or substantial portions of the Software.
23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
24 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29 | DEALINGS IN THE SOFTWARE.
30 |
--------------------------------------------------------------------------------
/tests/suites/casper/xpath.js:
--------------------------------------------------------------------------------
1 | /*eslint strict:0*/
2 | var x = require('casper').selectXPath;
3 |
4 | casper.test.begin('XPath tests', 6, function(test) {
5 | casper.start('tests/site/index.html', function() {
6 | test.assertExists({
7 | type: 'xpath',
8 | path: '/html/body/ul/li[2]'
9 | }, 'XPath selector can find an element');
10 | test.assertDoesntExist({
11 | type: 'xpath',
12 | path: '/html/body/ol/li[2]'
13 | }, 'XPath selector does not retrieve a nonexistent element');
14 | test.assertExists(x('/html/body/ul/li[2]'), 'selectXPath() shortcut can find an element as well');
15 | test.assertEvalEquals(function() {
16 | return __utils__.findAll({type: 'xpath', path: '/html/body/ul/li'}).length;
17 | }, 3, 'Correct number of elements are found');
18 | });
19 |
20 | casper.thenClick(x('/html/body/a[2]'), function() {
21 | test.assertTitle('CasperJS test form', 'Clicking XPath works as expected');
22 | this.fill(x('/html/body/form'), {
23 | email: 'chuck@norris.com'
24 | });
25 | test.assertEvalEquals(function() {
26 | return document.querySelector('input[name="email"]').value;
27 | }, 'chuck@norris.com', 'Casper.fill() can fill an input[type=text] form field');
28 | });
29 |
30 | casper.run(function() {
31 | test.done();
32 | });
33 | });
34 |
--------------------------------------------------------------------------------
/tests/suites/casper/content.js:
--------------------------------------------------------------------------------
1 | /*eslint strict:0*/
2 | var fs = require("fs");
3 |
4 | casper.test.begin("Casper.getPageContent() text/html content", 1, function(test) {
5 | casper.start("tests/site/test.html");
6 | casper.waitForUrl("tests/site/test.html", function() {
7 | test.assertMatch(this.getPageContent(), /CasperJS test target/,
8 | "Casper.getPageContent() retrieves text/html content");
9 | });
10 | casper.run(function() {
11 | test.done();
12 | });
13 | });
14 |
15 | casper.test.begin("Casper.getPageContent() non text/html content", 2, function(test) {
16 | // NOTE due to a bug in slimerjs we can only use text/* and
17 | // application/json content here
18 | // https://github.com/laurentj/slimerjs/issues/405
19 | casper.start("tests/site/dummy.json");
20 | casper.waitForUrl("tests/site/dummy.json", function() {
21 | test.assertEquals(this.getPageContent(), '{"dummy":"json"}\n',
22 | "Casper.getPageContent() retrieves application/json content");
23 | });
24 | casper.thenOpen("tests/site/dummy.txt");
25 | casper.waitForUrl("tests/site/dummy.txt", function() {
26 | test.assertEquals(this.getPageContent(), 'some dummy text\n',
27 | "Casper.getPageContent() retrieves text/plain content");
28 | });
29 |
30 | casper.run(function() {
31 | test.done();
32 | });
33 | });
34 |
--------------------------------------------------------------------------------
/samples/steptimeout.js:
--------------------------------------------------------------------------------
1 | /*eslint strict:0*/
2 | /*global CasperError, console, phantom, require*/
3 |
4 | var failed = [];
5 | var start = null;
6 | var links = [
7 | "http://google.com/'",
8 | "http://akei.com/'",
9 | "http://lemonde.fr/'",
10 | "http://liberation.fr/'",
11 | "http://cdiscount.fr/"
12 | ];
13 |
14 | var casper = require("casper").create({
15 | onStepTimeout: function() {
16 | failed.push(this.requestUrl);
17 | this.test.fail(this.requestUrl + " loads in less than " + timeout + "ms.");
18 | }
19 | });
20 |
21 | casper.on("load.finished", function() {
22 | this.echo(this.requestUrl + " loaded in " + (new Date() - start) + "ms", "PARAMETER");
23 | });
24 |
25 | var timeout = ~~casper.cli.get(0);
26 | casper.options.stepTimeout = timeout > 0 ? timeout : 1000;
27 |
28 | casper.echo("Testing with timeout=" + casper.options.stepTimeout + "ms, please be patient.");
29 |
30 | casper.start();
31 |
32 | casper.each(links, function(casper, link) {
33 | this.then(function() {
34 | this.test.comment("Loading " + link);
35 | start = new Date();
36 | this.open(link);
37 | });
38 | this.then(function() {
39 | var message = this.requestUrl + " loads in less than " + timeout + "ms.";
40 | if (failed.indexOf(this.requestUrl) === -1) {
41 | this.test.pass(message);
42 | }
43 | });
44 | });
45 |
46 | casper.run(function() {
47 | this.test.renderResults(true);
48 | });
49 |
--------------------------------------------------------------------------------
/tests/suites/casper/resources.js:
--------------------------------------------------------------------------------
1 | /*eslint strict:0*/
2 | casper.test.begin("Basic resources tests", 5, function(test) {
3 | casper.start("tests/site/resources.html", function() {
4 | test.assertEquals(this.resources.length, 1, "only one resource found");
5 | });
6 |
7 | casper.waitForResource("dummy.js", function() {
8 | test.assertEquals(this.resources.length, 2, "two resources found");
9 | test.assertResourceExists(/dummy\.js/i, "phantom image found via test RegExp");
10 | test.assertResourceExists(function(res) {
11 | return res.url.match("dummy.js");
12 | }, "phantom image found via test Function");
13 | test.assertResourceExists("dummy.js?querystring", "phantom image found via test String");
14 | }, function onTimeout() {
15 | test.fail("waitForResource timeout occured");
16 | });
17 |
18 | casper.run(function() {
19 | test.done();
20 | });
21 | });
22 |
23 | casper.test.begin('"resource.error" event', 3, function(test) {
24 | casper.on("resource.error", function(error) {
25 | test.assertType(error, "object", '"resource.error" triggered error information');
26 | test.assert(error.errorCode === 203, '"resource.error" error code is correct');
27 | test.assertMatch(error.url, /non-existant\.html$/, '"resource.error" url is correct');
28 | });
29 |
30 | casper.start('tests/site/non-existant.html').run(function() {
31 | casper.removeAllListeners("resource.error");
32 | test.done();
33 | });
34 | });
35 |
--------------------------------------------------------------------------------
/tests/suites/require.js:
--------------------------------------------------------------------------------
1 | /*eslint strict:0*/
2 | var fs = require('fs');
3 | var modroot = fs.pathJoin(phantom.casperPath, 'tests', 'sample_modules');
4 |
5 | casper.test.begin('Javascript module loading', 1, function(test) {
6 | var jsmod;
7 | try {
8 | jsmod = require(fs.pathJoin(modroot, 'jsmodule'));
9 | test.assertTrue(jsmod.ok, 'require() patched version can load a js module');
10 | } catch (e) {
11 | test.fail('require() patched version can load a js module');
12 | }
13 | test.done();
14 | });
15 |
16 | // only test if the engine supports coffeescript
17 | if (".coffee" in require.extensions) {
18 | casper.test.begin('CoffeeScript module loading', 1, function(test) {
19 | var csmod;
20 | try {
21 | csmod = require(fs.pathJoin(modroot, 'csmodule'));
22 | test.assertTrue(csmod.ok, 'require() patched version can load a coffeescript module');
23 | } catch (e) {
24 | test.fail('require() patched version can load a coffeescript module');
25 | }
26 | test.done();
27 | });
28 | }
29 |
30 | casper.test.begin('JSON module loading', 1, function(test) {
31 | var config;
32 | try {
33 | config = require(fs.pathJoin(modroot, 'config.json'));
34 | test.assertTrue(config.ok, 'require() patched version can load a json module');
35 | } catch (e) {
36 | test.fail('require() patched version can load a json module');
37 | }
38 | test.done();
39 | });
40 |
--------------------------------------------------------------------------------
/docs/index.rst:
--------------------------------------------------------------------------------
1 | ======================
2 | CasperJS documentation
3 | ======================
4 |
5 | CasperJS_ is a navigation scripting & testing utility for the PhantomJS_ (WebKit) and SlimerJS_ (Gecko) headless browsers, written in Javascript.
6 |
7 | .. figure:: _static/images/casperjs-logo.png
8 | :align: right
9 |
10 | .. toctree::
11 | :maxdepth: 2
12 |
13 | installation
14 | quickstart
15 | cli
16 | selectors
17 | testing
18 | modules/index
19 | writing_modules
20 | events-filters
21 | logging
22 | extending
23 | debugging
24 | faq
25 | cookbook
26 | changelog
27 | upgrading/index
28 | known_issues
29 | credits
30 | license
31 |
32 | You can also search the :ref:`genindex` if you're looking for something particular.
33 |
34 | .. index:: Community, Contributing, Help, Support
35 |
36 | Community
37 | ---------
38 |
39 | - `get the code `_ and `contribute `_
40 | - join the `mailing list `_
41 | - check out `the ecosystem `_
42 | - follow `@casperjs\_org `_ on Twitter
43 | - there's also a `Google+ account `_ (not much updated though)
44 |
45 |
46 | .. _CasperJS: http://casperjs.org/
47 | .. _PhantomJS: http://phantomjs.org/
48 | .. _SlimerJS: http://slimerjs.org/
49 |
--------------------------------------------------------------------------------
/docs/known_issues.rst:
--------------------------------------------------------------------------------
1 | .. _known_issues:
2 |
3 | .. index:: Known Issues
4 |
5 | Known Issues
6 | ============
7 | This is a non-exhaustive list of issues that the CasperJS team is aware of and tracking.
8 |
9 | PhantomJS
10 | ---------
11 | **Versions below 2.0.0**:
12 |
13 | - `phantomjs-issue-10795: `_
14 |
15 | There is a known issue while doing clicks within the page that causes execution to halt. It has been fixed in v2.0.0+ in phantomjs.
16 |
17 | It is mentioned in the following issues: `#233 `_
18 |
19 | ::
20 |
21 | console.log('START click');
22 | console.log(document.getElementById('foo').toString());
23 | console.log(document.getElementById('foo').click()); // this ends execution
24 | console.log('END click'); // this never gets called
25 |
26 | **Version 2.0.0**:
27 |
28 | - `phantomjs-issue-12506: `_
29 |
30 | Webpage.uploadFile is not working. It has been fixed in v2.0.1+ in phantomjs.
31 |
32 | - `phantomjs-issue-12410: `_
33 |
34 | Quote from `PhantomJS 2.0 Release Note `_:
35 |
36 | "PhantomJS 2 can not run scripts written in CoffeeScript anymore (see issue `12410 `_). As a workaround, CoffeeScript users can still compile their scripts to JavaScript first before executing it with PhantomJS."
--------------------------------------------------------------------------------
/samples/googlematch.coffee:
--------------------------------------------------------------------------------
1 | ###
2 | Takes provided terms passed as arguments and query google for the number of
3 | estimated results each have.
4 |
5 | Usage:
6 | $ casperjs googlematch.coffee nicolas chuck borris
7 | nicolas: 69600000
8 | chuck: 49500000
9 | borris: 2370000
10 | winner is "nicolas" with 69600000 results
11 | ###
12 |
13 | casper = require("casper").create verbose: true
14 |
15 | casper.fetchScore = ->
16 | @evaluate ->
17 | result = __utils__.findOne('#resultStats').innerText
18 | parseInt /Environ ([0-9\s]{1,}).*/.exec(result)[1].replace(/\s/g, '')
19 |
20 | terms = casper.cli.args # terms are passed through command-line arguments
21 |
22 | if terms.length < 2
23 | casper
24 | .echo("Usage: $ casperjs googlematch.js term1 term2 [term3]...")
25 | .exit(1)
26 |
27 | scores = []
28 |
29 | casper.echo "Let the match begin between \"#{terms.join '", "'}\"!"
30 |
31 | casper.start "http://google.fr/"
32 |
33 | casper.each terms, (self, term) ->
34 | @then -> @fill 'form[action="/search"]', { q: term }, true
35 | @then ->
36 | score = @fetchScore()
37 | scores.push term: term, score: score
38 | @echo "#{term}: #{score}"
39 |
40 | casper.run ->
41 | if scores.length is 0
42 | @echo "No result found"
43 | else
44 | scores.sort (a, b) -> b.score - a.score
45 | winner = scores[0]
46 | @echo "Winner is \"" + winner.term + "\" with " + winner.score + " results"
47 | @exit()
48 |
--------------------------------------------------------------------------------
/tests/suites/casper/events.js:
--------------------------------------------------------------------------------
1 | /*eslint strict:0*/
2 | casper.test.begin('events', 2, function(test) {
3 | casper.plopped = false;
4 | casper.once("plop", function() {
5 | this.plopped = true;
6 | });
7 | test.assert(Object.keys(casper._events).some(function(i) {
8 | return i === "plop";
9 | }), "on() has set an event handler");
10 | casper.emit("plop");
11 | test.assert(casper.plopped, "emit() emits an event");
12 | test.done();
13 | });
14 |
15 | casper.test.begin('filters', 3, function(test) {
16 | casper.foo = 0;
17 | casper.setFilter("test", function(a) {
18 | this.foo = 42;
19 | return a + 1;
20 | });
21 | test.assert(Object.keys(casper._filters).some(function(i) {
22 | return i === "test";
23 | }), "setFilter() has set a filter");
24 | test.assertEquals(casper.filter("test", 1), 2, "filter() filters a value");
25 | test.assertEquals(casper.foo, 42, "filter() applies the correct context");
26 | delete casper.foo;
27 | test.done();
28 | });
29 |
30 | casper.test.begin('events order', 2, function(test) {
31 | casper.mowed = "Moo";
32 | casper.on("mow", function() {
33 | this.mowed = casper.mowed + " Moo";
34 | });
35 | casper.emit("mow");
36 | test.assertEquals(casper.mowed, "Moo Moo", "mowed has the correct value");
37 |
38 | casper.prependListener("mow", function() {
39 | this.mowed = this.mowed + " Boo";
40 | });
41 | casper.emit("mow");
42 | test.assertEquals(casper.mowed, "Moo Moo Boo Moo", "mowed has the correct value");
43 | test.done();
44 | });
45 |
--------------------------------------------------------------------------------
/samples/googletesting.js:
--------------------------------------------------------------------------------
1 | /*eslint strict:0*/
2 | /*global CasperError, casper, console, phantom, require*/
3 | /**
4 | * Google sample testing.
5 | *
6 | * Usage:
7 | *
8 | * $ casperjs test googletesting.js
9 | */
10 | casper.test.begin('Google search retrieves 10 or more results', 5, function suite(test) {
11 | casper.start("http://www.google.fr/", function() {
12 | test.assertTitle("Google", "google homepage title is the one expected");
13 | test.assertExists('form[action="/search"]', "main form is found");
14 | this.fill('form[action="/search"]', {
15 | q: "casperjs"
16 | }, true);
17 | });
18 |
19 | casper.then(function() {
20 | test.assertTitle("casperjs - Recherche Google", "google title is ok");
21 | test.assertUrlMatch(/q=casperjs/, "search term has been submitted");
22 | test.assertEval(function() {
23 | return __utils__.findAll("h3.r").length >= 10;
24 | }, "google search for \"casperjs\" retrieves 10 or more results");
25 | });
26 |
27 | casper.run(function() {
28 | test.done();
29 | });
30 | });
31 |
32 | casper.test.begin('Casperjs.org is first ranked', 1, function suite(test) {
33 | casper.start("http://www.google.fr/", function() {
34 | this.fill('form[action="/search"]', {
35 | q: "casperjs"
36 | }, true);
37 | });
38 |
39 | casper.then(function() {
40 | test.assertSelectorContains(".g", "casperjs.org", "casperjs.org is first ranked");
41 | });
42 |
43 | casper.run(function() {
44 | test.done();
45 | });
46 | });
47 |
--------------------------------------------------------------------------------
/tests/suites/casper/request.js:
--------------------------------------------------------------------------------
1 | /*eslint strict:0*/
2 | var currentRequest;
3 |
4 | function onResourceRequested(requestData, request) {
5 | currentRequest = requestData;
6 | }
7 |
8 | function testHeader(header) {
9 | return header.name === 'Accept' && header.value === 'application/json';
10 | }
11 |
12 | casper.test.begin('requests tests', 3, {
13 | setUp: function() {
14 | casper.on('page.resource.requested', onResourceRequested);
15 | },
16 |
17 | tearDown: function() {
18 | currentRequest = undefined;
19 | casper.removeListener('page.resource.requested', onResourceRequested);
20 | },
21 |
22 | test: function(test) {
23 | casper.start('tests/site/index.html', function() {
24 | test.assertNot(currentRequest.headers.some(testHeader),
25 | "Casper.open() sets no custom header by default");
26 | });
27 |
28 | casper.thenOpen('tests/site/index.html', {
29 | headers: {
30 | Accept: 'application/json'
31 | }
32 | }, function() {
33 | test.assert(currentRequest.headers.some(testHeader),
34 | "Casper.open() can set a custom header");
35 | });
36 |
37 | casper.thenOpen('tests/site/index.html', function() {
38 | test.assertNot(currentRequest.headers.some(testHeader),
39 | "Casper.open() custom headers option is not persistent");
40 | });
41 |
42 | casper.run(function() {
43 | this.removeAllListeners('page.resource.requested');
44 | test.done();
45 | });
46 | }
47 | });
48 |
--------------------------------------------------------------------------------
/tests/suites/casper/frames.js:
--------------------------------------------------------------------------------
1 | /*eslint strict:0*/
2 | casper.test.begin('handling frames', 16, function(test) {
3 | casper.start('tests/site/frames.html');
4 |
5 | casper.withFrame('frame1', function() {
6 | test.assertTitle('CasperJS frame 1');
7 | test.assertExists("#f1");
8 | test.assertDoesntExist("#f2");
9 | test.assertEval(function() {
10 | return '__utils__' in window && 'getBinary' in __utils__;
11 | }, '__utils__ object is available in child frame');
12 | test.assertMatches(this.page.frameContent, /This is frame 1/);
13 | test.assertMatches(this.getHTML(), /This is frame 1/);
14 | });
15 |
16 | casper.withFrame('frame2', function() {
17 | test.assertTitle('CasperJS frame 2');
18 | test.assertExists("#f2");
19 | test.assertDoesntExist("#f1");
20 | test.assertEval(function() {
21 | return '__utils__' in window && 'getBinary' in __utils__;
22 | }, '__utils__ object is available in other child frame');
23 | this.clickLabel('frame 3');
24 | });
25 |
26 | casper.withFrame('frame2', function() {
27 | test.assertTitle('CasperJS frame 3');
28 | });
29 |
30 | casper.withFrame(0, function() {
31 | test.assertTitle('CasperJS frame 1');
32 | test.assertExists("#f1");
33 | test.assertDoesntExist("#f2");
34 | });
35 |
36 | casper.withFrame(1, function() {
37 | test.assertTitle('CasperJS frame 3');
38 | });
39 |
40 | casper.run(function() {
41 | test.assertTitle('CasperJS test frames');
42 | test.done();
43 | });
44 | });
45 |
--------------------------------------------------------------------------------
/tests/suites/casper/confirm.js:
--------------------------------------------------------------------------------
1 | /*eslint strict:0*/
2 | casper.test.begin('can confirm dialog', 2, {
3 | received: undefined,
4 |
5 | setUp: function(test) {
6 | var self = this;
7 | casper.removeAllFilters('page.confirm');
8 | casper.setFilter('page.confirm', function(message) {
9 | self.received = message;
10 | return true;
11 | });
12 | },
13 |
14 | tearDown: function(test) {
15 | casper.removeAllFilters('page.confirm');
16 | },
17 |
18 | test: function(test) {
19 | var self = this;
20 | casper.start('tests/site/confirm.html', function() {
21 | test.assert(this.getGlobal('confirmed'), 'confirmation dialog accepted');
22 | }).run(function() {
23 | test.assertEquals(self.received, 'are you sure?', 'confirmation message is ok');
24 | test.done();
25 | });
26 | }
27 | });
28 |
29 | casper.test.begin('can cancel dialog', 1, {
30 | received: undefined,
31 |
32 | setUp: function(test) {
33 | var self = this;
34 | casper.removeAllFilters('page.confirm');
35 | casper.setFilter('page.confirm', function(message) {
36 | return false;
37 | });
38 | },
39 |
40 | tearDown: function(test) {
41 | casper.removeAllFilters('page.confirm');
42 | },
43 |
44 | test: function(test) {
45 | var self = this;
46 | casper.start('tests/site/confirm.html', function() {
47 | test.assertNot(this.getGlobal('confirmed'), 'confirmation dialog canceled');
48 | }).run(function() {
49 | test.done();
50 | });
51 | }
52 | });
53 |
--------------------------------------------------------------------------------
/samples/multirun.js:
--------------------------------------------------------------------------------
1 | /*eslint strict:0*/
2 | /*global CasperError, console, phantom, require*/
3 |
4 | var casper = require("casper").create({
5 | verbose: true
6 | });
7 |
8 | var countLinks = function() {
9 | return document.querySelectorAll('a').length;
10 | };
11 |
12 | var suites = [
13 | function() {
14 | this.echo("Suite 1");
15 | this.start("http://google.com/", function() {
16 | this.echo("Page title: " + (this.getTitle()));
17 | });
18 | this.then(function() {
19 | this.echo((this.evaluate(countLinks)) + " links");
20 | });
21 | }, function() {
22 | this.echo("Suite 2");
23 | this.start("http://yahoo.com/", function() {
24 | this.echo("Page title: " + (this.getTitle()));
25 | });
26 | this.then(function() {
27 | this.echo((this.evaluate(countLinks)) + " links");
28 | });
29 | }, function() {
30 | this.echo("Suite 3");
31 | this.start("http://bing.com/", function() {
32 | this.echo("Page title: " + (this.getTitle()));
33 | });
34 | this.then(function() {
35 | this.echo((this.evaluate(countLinks)) + " links");
36 | });
37 | }
38 | ];
39 |
40 | casper.start();
41 |
42 | casper.then(function() {
43 | this.echo("Starting");
44 | });
45 |
46 | var currentSuite = 0;
47 |
48 | var check = function() {
49 | if (suites[currentSuite]) {
50 | suites[currentSuite].call(this);
51 | currentSuite++;
52 | casper.run(check);
53 | } else {
54 | this.echo("All done.");
55 | this.exit();
56 | }
57 | };
58 |
59 | casper.run(check);
60 |
--------------------------------------------------------------------------------
/samples/dynamic.coffee:
--------------------------------------------------------------------------------
1 | casper = require("casper").create
2 | verbose: true
3 |
4 | # The base links array
5 | links = [
6 | "http://google.com/"
7 | "http://yahoo.com/"
8 | "http://bing.com/"
9 | ]
10 |
11 | currentLink = 0;
12 |
13 | # If we don't set a limit, it could go on forever
14 | upTo = ~~casper.cli.get(0) || 10
15 |
16 | ###
17 | Get the links, and add them to the links array
18 | (It could be done all in one step, but it is intentionally splitted)
19 | ###
20 | addLinks = (link) ->
21 | @then ->
22 | found = @evaluate searchLinks
23 | @echo "#{found.length} links found on #{link}"
24 | links = links.concat found
25 |
26 | ###
27 | Fetch all elements from the page and return
28 | the ones which contains a href starting with 'http://'
29 | ###
30 | searchLinks = ->
31 | filter = Array::filter
32 | map = Array::map
33 | map.call filter.call(document.querySelectorAll("a"), (a) ->
34 | (/^http:\/\/.*/i).test a.getAttribute("href")
35 | ), (a) ->
36 | a.getAttribute "href"
37 |
38 | # Just opens the page and prints the title
39 | start = (link) ->
40 | @start link, ->
41 | @echo "Page title: #{ @getTitle() }"
42 |
43 | # As long as it has a next link, and is under the maximum limit, will keep running
44 | check = ->
45 | if links[currentLink] && currentLink < upTo
46 | @echo "--- Link #{currentLink} ---"
47 | start.call @, links[currentLink]
48 | addLinks.call @, links[currentLink]
49 | currentLink++
50 | @run check
51 | else
52 | @echo "All done."
53 | @exit()
54 |
55 | casper.start()
56 |
57 | casper.then ->
58 | @echo "Starting"
59 |
60 | casper.run check
61 |
--------------------------------------------------------------------------------
/tests/suites/casper/capture.js:
--------------------------------------------------------------------------------
1 | /*eslint strict:0*/
2 | var fs = require('fs');
3 |
4 | casper.test.begin('Casper.capture() tests', 1, {
5 | testFile: '/tmp/__casper_test_capture.png',
6 |
7 | setUp: function(test) {
8 | if (fs.exists(this.testFile) && fs.isFile(this.testFile)) {
9 | try {
10 | fs.remove(this.testFile);
11 | } catch (e) {
12 | }
13 | }
14 | },
15 |
16 | tearDown: function(test) {
17 | try {
18 | fs.remove(this.testFile);
19 | } catch(e) {
20 | }
21 | },
22 |
23 | test: function(test) {
24 | var self = this;
25 |
26 | casper.start('tests/site/index.html', function() {
27 | this.viewport(300, 200);
28 | this.capture(self.testFile);
29 | test.assert(fs.isFile(self.testFile), 'Casper.capture() captured a screenshot');
30 | });
31 |
32 | casper.run(function() {
33 | test.done();
34 | });
35 | }
36 | });
37 |
38 | casper.test.begin('Casper.captureBase64() tests', 3, function(test) {
39 | casper.start('tests/site/index.html', function() {
40 | test.assert(this.captureBase64('png').length > 0,
41 | 'Casper.captureBase64() rendered a page capture as base64');
42 | test.assert(this.captureBase64('png', 'ul').length > 0,
43 | 'Casper.captureBase64() rendered a capture from a selector as base64');
44 | test.assert(this.captureBase64('png', {top: 0, left: 0, width: 30, height: 30}).length > 0,
45 | 'Casper.captureBase64() rendered a capture from a clipRect as base64');
46 | }).run(function() {
47 | test.done();
48 | });
49 | });
50 |
--------------------------------------------------------------------------------
/samples/googlepagination.js:
--------------------------------------------------------------------------------
1 | /*eslint strict:0*/
2 | /*global CasperError, console, phantom, require*/
3 |
4 | /**
5 | * Capture multiple pages of google search results
6 | *
7 | * Usage: $ casperjs googlepagination.coffee my search terms
8 | *
9 | * (all arguments will be used as the query)
10 | */
11 |
12 | var casper = require("casper").create({
13 | waitTimeout: 1000,
14 | pageSettings: {
15 | userAgent: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:23.0) Gecko/20130404 Firefox/23.0"
16 | }
17 | });
18 | var currentPage = 1;
19 |
20 | if (casper.cli.args.length === 0) {
21 | casper
22 | .echo("Usage: $ casperjs googlepagination.js my search terms")
23 | .exit(1)
24 | ;
25 | }
26 |
27 | var terminate = function() {
28 | this.echo("that's all, folks.").exit();
29 | };
30 |
31 | var processPage = function() {
32 | var url;
33 | this.echo("capturing page " + currentPage);
34 | this.capture("google-results-p" + currentPage + ".png");
35 |
36 | // don't go too far down the rabbit hole
37 | if (currentPage >= 5 || !this.exists("#pnnext")) {
38 | return terminate.call(casper);
39 | }
40 |
41 | currentPage++;
42 | this.echo("requesting next page: " + currentPage);
43 | url = this.getCurrentUrl();
44 | this.thenClick("#pnnext").then(function() {
45 | this.waitFor(function() {
46 | return url !== this.getCurrentUrl();
47 | }, processPage, terminate);
48 | });
49 | };
50 |
51 | casper.start("http://google.fr/", function() {
52 | this.fill('form[action="/search"]', {
53 | q: casper.cli.args.join(" ")
54 | }, true);
55 | });
56 |
57 | casper.waitForSelector('#pnnext', processPage, terminate);
58 |
59 | casper.run();
60 |
--------------------------------------------------------------------------------
/tests/suites/casper/navigation.js:
--------------------------------------------------------------------------------
1 | /*eslint strict:0*/
2 | var server = require('webserver').create();
3 | var service = server.listen(8090, function(request, response) {
4 | response.statusCode = 200;
5 | response.setHeader('Content-type', 'text/html');
6 | response.write(' a link ');
7 | response.write('');
8 | response.close();
9 | });
10 |
11 | casper.test.begin('Link Navigation updates response', 2, function(test) {
12 | casper.start('http://localhost:8090', function(response) {
13 | casper.click('a');
14 | casper.then(function(response) {
15 | test.assertUrlMatch(
16 | /\/link$/,
17 | 'URL matches anchor href'
18 | );
19 | test.assertEquals(
20 | response.url,
21 | casper.page.url,
22 | 'response is consistent with the internal page'
23 | );
24 |
25 | });
26 | }).run(function() {
27 | test.done();
28 | });
29 | });
30 |
31 | casper.test.begin('Form Submittal updates the response', 2, function(test) {
32 | casper.start('http://localhost:8090', function(response) {
33 | casper.fill('form', {}, true);
34 | casper.then(function(response) {
35 | test.assertUrlMatch(
36 | /\/form$/,
37 | 'URL matches form action'
38 | );
39 | test.assertEquals(
40 | response.url,
41 | casper.page.url,
42 | 'response is consistent with the internal page'
43 | );
44 | });
45 | }).run(function() {
46 | test.done();
47 | server.close();
48 | });
49 | });
50 |
--------------------------------------------------------------------------------
/docs/credits.rst:
--------------------------------------------------------------------------------
1 | Credits
2 | =======
3 |
4 | Author
5 | ------
6 |
7 | CasperJS is mainly developed by `Nicolas Perriault `_ on its free time.
8 |
9 | If you want to thank him and/or sponsor the development of CasperJS, please consider donating (see links in the sidebar).
10 |
11 | Contributors
12 | ------------
13 |
14 | These people have contributed to CasperJS:
15 |
16 | - Brikou CARRE
17 | - Thomas Parisot
18 | - Han Yu
19 | - Chris Lorenzo
20 | - Victor Yap
21 | - Rob Barreca
22 | - Tyler Ritchie
23 | - Nick Rabinowitz
24 | - Pascal Borreli
25 | - Dave Lee
26 | - Andrew Childs
27 | - Solomon White
28 | - Reina Sweet
29 | - Jan Schaumann
30 | - Elmar Langholz
31 | - Clochix
32 | - Donovan Hutchinson
33 | - Julien Moulin
34 | - Michael Geers
35 | - Jason Funk
36 | - Vladimir Chizhov
37 | - Jean-Philippe Serafin
38 | - snkashis
39 | - Rafael
40 | - Andrew de Andrade
41 | - Ben Lowery
42 | - Chris Winters
43 | - Christophe Benz
44 | - Harrison Reiser
45 | - Jan Pochyla
46 | - Jan-Martin Fruehwacht
47 | - Julian Gruber
48 | - Justin Slattery
49 | - Justine Tunney
50 | - KaroDidi
51 | - Leandro Boscariol
52 | - Maisons du monde
53 | - Marcel Duran
54 | - Mathieu Agopian
55 | - Mehdi Kabab
56 | - Mikko Peltonen
57 | - Rafael Garcia
58 | - Raphaël Benitte
59 | - Tim Bunce
60 |
61 | Logo
62 | ----
63 |
64 | CasperJS logo designed by `Jeremy Forveille `_
65 |
66 | You can download the logo sources here:
67 |
68 | - `logo CasperJS (PDF) <_static/images/logo_casperjs.pdf>`_
69 | - `logo CasperJS (EPS) <_static/images/logo_casperjs.eps>`_
70 | - `logo CasperJS (AI) <_static/images/logo_casperjs.ai>`_
71 |
72 | These assets are under `MIT license `_
73 |
--------------------------------------------------------------------------------
/tests/suites/casper/viewport.js:
--------------------------------------------------------------------------------
1 | /*eslint strict:0*/
2 | var utils = require('utils');
3 |
4 | casper.test.begin('viewport() tests', 3, function(test) {
5 | casper.start();
6 | casper.viewport(1337, 999);
7 | test.assertEquals(casper.page.viewportSize.width, 1337,
8 | 'Casper.viewport() can change the width of page viewport');
9 | test.assertEquals(casper.page.viewportSize.height, 999,
10 | 'Casper.viewport() can change the height of page viewport');
11 | test.assertRaises(casper.viewport, ['a', 'b'],
12 | 'Casper.viewport() validates viewport size data');
13 | test.done();
14 | });
15 |
16 | casper.test.begin('viewport() asynchronous tests', 2, function(test) {
17 | var screenshotData;
18 |
19 | casper.start('tests/site/index.html').viewport(800, 600, function() {
20 | this.setContent(utils.format(' ',
21 | this.captureBase64('png',{
22 | top: 0,
23 | left: 0,
24 | width: 800,
25 | height: 600
26 | })));
27 | });
28 |
29 | casper.then(function() {
30 | var imgInfo = this.getElementInfo('img');
31 | // sometimes, setting viewport could take more time in slimerjs/gecko
32 | // and the image is not still ready: :-/
33 | if (!test.skipIfEngine(2, {
34 | name: 'slimerjs',
35 | message: 'Casper.viewport() change test'
36 | })) {
37 | test.assertEquals(imgInfo.width, 800, 'Casper.viewport() changes width asynchronously');
38 | test.assertEquals(imgInfo.height, 600, 'Casper.viewport() changes height asynchronously');
39 | }
40 | });
41 |
42 | casper.run(function() {
43 | test.done();
44 | });
45 | });
46 |
--------------------------------------------------------------------------------
/tests/suites/casper/encodedurl.js:
--------------------------------------------------------------------------------
1 | /*eslint strict:0*/
2 |
3 | var urlWithEncodedSpace = 'tests/site/has%20space.html';
4 | var urlWithoutSpace = 'tests/site/index.html';
5 |
6 | var urls = [urlWithEncodedSpace, urlWithoutSpace];
7 | if (casper.cli.options.reverse) urls.reverse();
8 |
9 | var phantomVersion = 'phantomjs ' + phantom.version.major + '.' + phantom.version.minor + '.' + phantom.version.patch;
10 |
11 | var numPageResourcesRequested = 0;
12 | var numPageResourcesReceived = 0;
13 |
14 | casper.on ('page.resource.requested', function ResourceRequested (resource) {
15 | ++numPageResourcesRequested;
16 | });
17 |
18 | casper.on ('page.resource.received', function ResourceReceived (resource) {
19 | ++numPageResourcesReceived;
20 | });
21 |
22 | casper.test.begin(phantomVersion + ' ' + urls[0] + ' then ' + urls[1], 8, function(test) {
23 |
24 | casper.start(urls[0], function CheckResponse1(response1) {
25 | test.assertEquals(numPageResourcesRequested, 1, 'page.resource.requested 1');
26 | test.assertEquals(numPageResourcesReceived, 1, 'page.resource.received 1');
27 | test.assertEquals(response1.status, 200, 'status 200 for ' + urls[0]);
28 | test.assertEquals(response1.url, casper.filter('open.location', urls[0]) || urls[0], 'opened ' + urls[0]); // Mimic Casper.prototype.open
29 |
30 | casper.thenOpen (urls[1], function CheckResponse2(response2) {
31 | test.assertEquals(numPageResourcesRequested, 2, 'page.resource.requested 2');
32 | test.assertEquals(numPageResourcesReceived, 2, 'page.resource.received 2');
33 | test.assertEquals(response2.status, 200, 'status 200 for ' + urls[1]);
34 | test.assertEquals(response2.url, casper.filter('open.location', urls[1]) || urls[1], 'opened ' + urls[1]); // Mimic Casper.prototype.open
35 | });
36 | });
37 |
38 | casper.run(function() {
39 | test.done();
40 | });
41 | });
42 |
--------------------------------------------------------------------------------
/tests/suites/casper/logging.js:
--------------------------------------------------------------------------------
1 | /*eslint strict:0*/
2 |
3 | casper.test.begin('logging tests', 4, function(test) {
4 | var oldLevel;
5 | casper.start('tests/site/index.html');
6 |
7 | casper.then(casper.createStep(function() {
8 | oldLevel = casper.options.logLevel;
9 |
10 | casper.result.log = [];
11 | casper.options.logLevel = 'info';
12 | casper.options.verbose = false;
13 | }, {skipLog: true}));
14 |
15 | casper.then(casper.createStep(function() {
16 | casper.log('foo', 'info');
17 | }, {skipLog: true}));
18 |
19 | casper.then(casper.createStep(function() {
20 | test.assert(casper.result.log.some(function(e) {
21 | return e.message === 'foo' && e.level === 'info';
22 | }), 'Casper.log() adds a log entry');
23 | }, {skipLog: true}));
24 |
25 | casper.then(casper.createStep(function() {
26 | casper.options.logLevel = 'debug';
27 | casper.options.verbose = false;
28 | casper.evaluate(function() {
29 | __utils__.log('debug message');
30 | __utils__.log('info message', 'info');
31 | });
32 | }, {skipLog: true}));
33 |
34 | casper.then(casper.createStep(function() {
35 | test.assert(casper.result.log.some(function(e) {
36 | return e.message === 'debug message' && e.level === 'debug' && e.space === 'remote';
37 | }), 'ClientUtils.log() adds a log entry');
38 | test.assert(casper.result.log.some(function(e) {
39 | return e.message === 'info message' && e.level === 'info' && e.space === 'remote';
40 | }), 'ClientUtils.log() adds a log entry at a given level');
41 | test.assertEquals(this.result.log.length, 3, 'Casper.log() logged messages');
42 | }, {skipLog: true}));
43 |
44 | casper.run(function() {
45 | test.done();
46 | casper.options.logLevel = oldLevel;
47 | casper.options.verbose = true;
48 | });
49 | });
50 |
--------------------------------------------------------------------------------
/tests/suites/casper/fetchtext.js:
--------------------------------------------------------------------------------
1 | /*eslint strict:0*/
2 | casper.test.begin('fetchText() basic tests', 1, function(test) {
3 | casper.start('tests/site/index.html', function() {
4 | test.assertEquals(this.fetchText('ul li'), 'onetwothree',
5 | 'Casper.fetchText() can retrieve text contents');
6 | }).run(function() {
7 | test.done();
8 | });
9 | });
10 |
11 | casper.test.begin('fetchText() basic tests', 1, function(test) {
12 | casper.start('tests/site/index.html', function() {
13 | test.assertEquals(this.fetchText('input[name="dummy_name"]'), 'dummy_value',
14 | 'Casper.fetchText() can retrieve text contents from an input element');
15 | }).run(function() {
16 | test.done();
17 | });
18 | });
19 |
20 | casper.test.begin('fetchText() handles HTML entities', 1, function(test) {
21 | casper.start().then(function() {
22 | this.setContent('Voilà');
23 | test.assertEquals(this.fetchText('body'), 'Voilà',
24 | 'Casper.fetchText() fetches decoded text');
25 | });
26 | casper.run(function() {
27 | test.done();
28 | });
29 | });
30 |
31 | casper.test.begin('fetchText() handles empty elements', 1, function(test) {
32 | casper.start().then(function() {
33 | this.setContent('');
34 | test.assertEquals(this.fetchText('body'), '',
35 | 'Casper.fetchText() fetches empty string');
36 | });
37 | casper.run(function() {
38 | test.done();
39 | });
40 | });
41 |
42 | casper.test.begin('fetchText() handles plain texts', 1, function(test) {
43 | casper.start().then(function() {
44 | this.setContent('This is a plain text.');
45 | test.assertEquals(this.fetchText('html'), 'This is a plain text.',
46 | 'Casper.fetchText() handles plain texts');
47 | });
48 | casper.run(function() {
49 | test.done();
50 | });
51 | });
52 |
--------------------------------------------------------------------------------
/samples/googlematch.js:
--------------------------------------------------------------------------------
1 | /*eslint strict:0*/
2 | /*global CasperError, console, phantom, require*/
3 |
4 | /**
5 | * Takes provided terms passed as arguments and query google for the number of
6 | * estimated results each have.
7 | *
8 | * Usage:
9 | * $ casperjs googlematch.js nicolas chuck borris
10 | * nicolas: 69600000
11 | * chuck: 49500000
12 | * borris: 2370000
13 | * winner is "nicolas" with 69600000 results
14 | */
15 |
16 | var casper = require("casper").create({
17 | verbose: true
18 | });
19 |
20 | casper.fetchScore = function() {
21 | return this.evaluate(function() {
22 | var result = __utils__.findOne('#resultStats').innerText;
23 | return parseInt(/Environ ([0-9\s]{1,}).*/.exec(result)[1].replace(/\s/g, ''), 10);
24 | });
25 | };
26 |
27 | var terms = casper.cli.args;
28 |
29 | if (terms.length < 2) {
30 | casper
31 | .echo("Usage: $ casperjs googlematch.js term1 term2 [term3]...")
32 | .exit(1)
33 | ;
34 | }
35 |
36 | var scores = [];
37 |
38 | casper.echo("Let the match begin between \"" + (terms.join('", "')) + "\"!");
39 |
40 | casper.start("http://google.fr/");
41 |
42 | casper.each(terms, function(casper, term, i) {
43 | this.echo('Fetching score for ' + term);
44 | this.then(function() {
45 | this.fill('form[action="/search"]', {q: '"' + term + '"'}, true);
46 | });
47 | this.then(function() {
48 | var score = this.fetchScore();
49 | scores.push({
50 | term: term,
51 | score: score
52 | });
53 | this.echo(term + ': ' + score);
54 | });
55 | });
56 |
57 | casper.run(function() {
58 | if (scores.length === 0) {
59 | this.echo("No result found");
60 | } else {
61 | scores.sort(function(a, b) {
62 | return b.score - a.score;
63 | });
64 | var winner = scores[0];
65 | this.echo("Winner is \"" + winner.term + "\" with " + winner.score + " results");
66 | }
67 | this.exit();
68 | });
69 |
--------------------------------------------------------------------------------
/samples/dynamic.js:
--------------------------------------------------------------------------------
1 | /*eslint strict:0*/
2 | /*global CasperError, console, phantom, require*/
3 |
4 | var casper = require("casper").create({
5 | verbose: true
6 | });
7 |
8 | // The base links array
9 | var links = [
10 | "http://google.com/",
11 | "http://yahoo.com/",
12 | "http://bing.com/"
13 | ];
14 |
15 | // If we don't set a limit, it could go on forever
16 | var upTo = ~~casper.cli.get(0) || 10;
17 |
18 | var currentLink = 0;
19 |
20 | // Get the links, and add them to the links array
21 | // (It could be done all in one step, but it is intentionally splitted)
22 | function addLinks(link) {
23 | this.then(function() {
24 | var found = this.evaluate(searchLinks);
25 | this.echo(found.length + " links found on " + link);
26 | links = links.concat(found);
27 | });
28 | }
29 |
30 | // Fetch all elements from the page and return
31 | // the ones which contains a href starting with 'http://'
32 | function searchLinks() {
33 | var filter, map;
34 | filter = Array.prototype.filter;
35 | map = Array.prototype.map;
36 | return map.call(filter.call(document.querySelectorAll("a"), function(a) {
37 | return (/^http:\/\/.*/i).test(a.getAttribute("href"));
38 | }), function(a) {
39 | return a.getAttribute("href");
40 | });
41 | }
42 |
43 | // Just opens the page and prints the title
44 | function start(link) {
45 | this.start(link, function() {
46 | this.echo('Page title: ' + this.getTitle());
47 | });
48 | }
49 |
50 | // As long as it has a next link, and is under the maximum limit, will keep running
51 | function check() {
52 | if (links[currentLink] && currentLink < upTo) {
53 | this.echo('--- Link ' + currentLink + ' ---');
54 | start.call(this, links[currentLink]);
55 | addLinks.call(this, links[currentLink]);
56 | currentLink++;
57 | this.run(check);
58 | } else {
59 | this.echo("All done.");
60 | this.exit();
61 | }
62 | }
63 |
64 | casper.start().then(function() {
65 | this.echo("Starting");
66 | });
67 |
68 | casper.run(check);
69 |
--------------------------------------------------------------------------------
/tests/suites/casper/urls.js:
--------------------------------------------------------------------------------
1 | /*eslint strict:0*/
2 |
3 | casper.test.begin('urls tests', 9, function(test) {
4 | var assertURL = function(match, message) {
5 | test.assertHttpStatus(200);
6 | test.assertUrlMatches(match, message);
7 | };
8 |
9 | casper.start('tests/site/urls.html#fragment');
10 |
11 | casper.waitForUrl(/urls.html/, function() {
12 | assertURL('urls.html', 'Casper.start loads URL with fragment');
13 | test.assertEqual(casper.evaluate(function() {
14 | return location.hash;
15 | }), '#fragment', 'location.hash equals fragment');
16 | });
17 |
18 | casper.then(function() {
19 | this.clickLabel('raw unicode', 'a');
20 | });
21 |
22 | casper.waitForUrl(/Forlì/,
23 | assertURL.bind(this,
24 | 'Forlì',
25 | 'Casper.getCurrentUrl() retrieves a raw unicode URL'
26 | ));
27 |
28 | casper.then(function() {
29 | this.clickLabel('escaped', 'a');
30 | });
31 |
32 | casper.waitForUrl(/Farlì/,
33 | assertURL.bind(this,
34 | 'Farlì',
35 | 'Casper.getCurrentUrl() retrieves an escaped URL'
36 | ));
37 |
38 | casper.then(function() {
39 | this.clickLabel('uri encoded', 'a');
40 | });
41 |
42 | casper.waitForUrl(/Furlì/,
43 | assertURL.bind(this,
44 | 'Furlì',
45 | 'Casper.getCurrentUrl() retrieves a decoded URL'
46 | ));
47 |
48 | casper.run(function() {
49 | test.done();
50 | });
51 | });
52 |
53 | // https://github.com/casperjs/casperjs/issues/841
54 | casper.test.begin('url tests with javascript disabled', 1, function(test) {
55 | casper.options.pageSettings.javascriptEnabled = false;
56 | casper.start('tests/site/urls.html');
57 | casper.then(function() {
58 | test.assertMatch(this.getCurrentUrl(), /urls\.html$/,
59 | 'Casper.getCurrentUrl() can work, with javascript disabled');
60 | });
61 | casper.run(function() {
62 | test.done();
63 | casper.options.pageSettings.javascriptEnabled = true;
64 | });
65 | });
66 |
--------------------------------------------------------------------------------
/CONTRIBUTORS.md:
--------------------------------------------------------------------------------
1 | # CasperJS contributors
2 |
3 | You can check out the [contribution graphs on github](https://github.com/casperjs/casperjs/graphs/contributors).
4 |
5 | ```
6 | $ git shortlog -s -n | cut -c8-
7 | Nicolas Perriault
8 | Mickaël Andrieu
9 | Laurent Jouanneau
10 | hexid
11 | Brikou CARRE
12 | oncletom
13 | Matt DuVall
14 | Nathan Black
15 | hannyu
16 | Julien Muetton
17 | Chris Bosco
18 | Matt Bowman
19 | Shiryaev Andrey
20 | mickaelandrieu
21 | Clochix
22 | Chris Lorenzo
23 | Victor Yap
24 | JF Paradis
25 | Matthew DuVall
26 | Rob Barreca
27 | Oleg Pudeyev
28 | pborreli
29 | nrabinowitz
30 | Darrell Hamilton
31 | Tyler Ritchie
32 | Andrew Childs
33 | Eric Bouchut
34 | Dave Lee
35 | Solomon White
36 | Luke Rodgers
37 | reina.sweet
38 | renatodarrigo
39 | Donovan Hutchinson
40 | Sean Massa
41 | Vladimir Chizhov
42 | Samuel Gabel
43 | Reina Sweet
44 | Jan Schaumann
45 | fwebdev
46 | Reid Lynch
47 | Justin Collum
48 | Philip Hansen
49 | Michael Geers
50 | Orchestrator81
51 | Nick Currier
52 | Julien Moulin
53 | Elmar Langholz
54 | Jason Funk
55 | Lee Byrd
56 | Thomas Rosenau
57 | V Sreekanth
58 | Patrick Reagan
59 | Andrew de Andrade
60 | Andy Shinn
61 | Ben Johnson
62 | Ben Lowery
63 | Bert Pareyn
64 | Brandon Bethke
65 | Charlie Park
66 | Chris Winters
67 | Christophe Benz
68 | Dharrya
69 | Dmitry Menshikov
70 | Florent DUBOST
71 | Harrison Reiser
72 | Itamar Nabriski
73 | Ivan
74 | Jamey J. DeOrio
75 | Jan Pochyla
76 | Jan-Martin Fruehwacht
77 | John F. Douthat
78 | Julian Gruber
79 | Justin Marsan
80 | Justin Slattery
81 | Justine Tunney
82 | KaroDidi
83 | Leandro Boscariol
84 | Maisons du monde
85 | Marcel Duran
86 | Mathieu Agopian
87 | Mehdi Kabab
88 | Miguel González
89 | Mikhail Korobov
90 | Mikko Peltonen
91 | Narno
92 | Pascal Borreli
93 | Phillip Alexander
94 | Rafael
95 | Rafael Garcia
96 | Raphaël Benitte
97 | Rock Li
98 | Scott
99 | Thomas Parisot
100 | Tim Bunce
101 | Tzvi Friedman
102 | Yasuo Ohgaki
103 | Yevgeny Smirnov
104 | alfetopito
105 | jayseeg
106 | jean-philippe serafin
107 | shekyan
108 | snkashis
109 | ```
110 |
--------------------------------------------------------------------------------
/docs/logging.rst:
--------------------------------------------------------------------------------
1 | .. _logging:
2 |
3 | .. index:: Logging, log levels
4 |
5 | =======
6 | Logging
7 | =======
8 |
9 | CasperJS allows logging using the :ref:`casper.log() ` method and these standard event levels:
10 |
11 | - ``debug``
12 | - ``info``
13 | - ``warning``
14 | - ``error``
15 |
16 | Sample use::
17 |
18 | var casper = require('casper').create();
19 | casper.log('plop', 'debug');
20 | casper.log('plip', 'warning');
21 |
22 | .. index:: verbose
23 |
24 | 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::
25 |
26 | var casper = require('casper').create({
27 | verbose: true
28 | });
29 |
30 | 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::
31 |
32 | var casper = require('casper').create({
33 | verbose: true,
34 | logLevel: 'debug'
35 | });
36 |
37 | You can also dump a JSON log of your Casper suite just by rendering the contents of the ``Casper.logs`` property::
38 |
39 | var casper = require('casper').create({
40 | // ...
41 | casper.run(function() {
42 | require('utils').dump(this.logs);
43 | this.exit();
44 | });
45 |
46 | Last, if you print log messages to the standard output using the ``verbose`` option, you'll get some fancy colors::
47 |
48 | var casper = require('casper').create({
49 | verbose: true,
50 | logLevel: 'debug'
51 | })
52 | casper.log('this is a debug message', 'debug');
53 | casper.log('and an informative one', 'info');
54 | casper.log('and a warning', 'warning');
55 | casper.log('and an error', 'error');
56 | casper.exit();
57 |
58 | This will give the following output:
59 |
60 | .. figure:: _static/images/logoutput.png
61 | :align: center
62 | :alt: image
63 |
64 | image
65 |
66 |
67 | .. hint::
68 |
69 | CasperJS doesn't write logs on the filesystem. You have to implement this by yourself if needed.
70 |
--------------------------------------------------------------------------------
/samples/bbcshots.coffee:
--------------------------------------------------------------------------------
1 | ###
2 | Create a mosaic image from all headline photos on BBC homepage
3 | ###
4 |
5 | casper = require("casper").create()
6 | nbLinks = 0
7 | currentLink = 1
8 | images = []
9 |
10 | # helper to hide some element from remote DOM
11 | casper.hide = (selector) ->
12 | @evaluate (selector) ->
13 | document.querySelector(selector).style.display = "none"
14 | , selector
15 |
16 | casper.start "http://www.bbc.co.uk/", ->
17 | nbLinks = @evaluate ->
18 | return __utils__.findAll('#promo2_carousel_items_items li').length
19 | @echo "#{nbLinks} items founds"
20 | # hide navigation arrows
21 | @hide ".nav_left"
22 | @hide ".nav_right"
23 | @mouse.move "#promo2_carousel"
24 |
25 | casper.waitUntilVisible ".autoplay.nav_pause", ->
26 | @echo "Moving over pause button"
27 | @mouse.move ".autoplay.nav_pause"
28 | @click ".autoplay.nav_pause"
29 | @echo "Clicked on pause button"
30 | @waitUntilVisible ".autoplay.nav_play", ->
31 | @echo "Carousel has been paused"
32 | # hide play button
33 | @hide ".autoplay"
34 |
35 | # Capture carrousel area
36 | next = ->
37 | image = "bbcshot#{currentLink}.png"
38 | images.push image
39 | @echo "Processing image #{currentLink}"
40 | @captureSelector image, '.carousel_viewport'
41 | if currentLink < nbLinks
42 | @click ".carousel_itemList_li[rel='#{currentLink}']"
43 | @wait 1000, ->
44 | @then next
45 | currentLink++
46 | else
47 | @then buildPage
48 |
49 | # Building resulting page and image
50 | buildPage = ->
51 | @echo "Build result page"
52 | fs = require "fs"
53 | @viewport 624, 400
54 | pageHtml = ""
55 | images.forEach (image) ->
56 | pageHtml += " "
57 | pageHtml += ""
58 | fs.write "result.html", pageHtml, 'w'
59 | @thenOpen "file://#{fs.workingDirectory}/result.html", ->
60 | @echo "Resulting image saved to result.png"
61 | @capture "result.png"
62 |
63 | casper.then next
64 |
65 | casper.run()
66 |
--------------------------------------------------------------------------------
/tests/suites/casper/steps.js:
--------------------------------------------------------------------------------
1 | /*eslint strict:0*/
2 | casper.test.begin('steps tests', 8, function(test) {
3 | casper.start('tests/site/index.html');
4 |
5 | var nsteps = casper.steps.length;
6 |
7 | casper.then(function(response) {
8 | test.assertTitle('CasperJS test index',
9 | 'Casper.then() added a new step');
10 | });
11 |
12 | test.assertEquals(casper.steps.length, nsteps + 1,
13 | 'Casper.then() can add a new step');
14 |
15 | casper.thenOpen('tests/site/test.html');
16 |
17 | test.assertEquals(casper.steps.length, nsteps + 2,
18 | 'Casper.thenOpen() can add a new step');
19 |
20 | casper.thenOpen('tests/site/test.html', function() {
21 | test.assertTitle('CasperJS test target',
22 | 'Casper.thenOpen() opened a location and executed a step');
23 | });
24 |
25 | test.assertEquals(casper.steps.length, nsteps + 4,
26 | 'Casper.thenOpen() can add a new step for opening, plus another step');
27 |
28 | casper.each([1, 2, 3], function(self, item, i) {
29 | test.assertEquals(i, item - 1,
30 | 'Casper.each() passes a contextualized index');
31 | });
32 |
33 | casper.run(function() {
34 | test.done();
35 | });
36 | });
37 |
38 | casper.test.begin('eachThen() tests', 2, function(test) {
39 | var received = [];
40 | var receivedFalsy = [];
41 |
42 | casper.start().eachThen([1, 2, 3], function(response) {
43 | if (!response) {
44 | test.fail('No response received');
45 | }
46 | received.push(response.data);
47 | });
48 |
49 | casper.then(function() {
50 | test.assertEquals(received, [1, 2, 3],
51 | 'Casper.eachThen() passes item to step data');
52 | });
53 |
54 | casper.eachThen([false, 0, ''], function(response) {
55 | if (!response) {
56 | test.fail('No response received');
57 | }
58 | receivedFalsy.push(response.data);
59 | });
60 |
61 | casper.then(function() {
62 | test.assertEquals(receivedFalsy, [false, 0, ''],
63 | 'Casper.eachThen() passes falsy items to step data');
64 | });
65 |
66 | casper.run(function() {
67 | test.done();
68 | });
69 | });
70 |
--------------------------------------------------------------------------------
/tests/suites/tester/testsuite.js:
--------------------------------------------------------------------------------
1 | /*eslint strict:0*/
2 | /*global CasperError, casper, console, phantom, require*/
3 |
4 | var TestCaseResult = require('tester').TestCaseResult,
5 | TestSuiteResult = require('tester').TestSuiteResult;
6 |
7 | function generateCaseResult(options) {
8 | var i,
9 | nPasses = options && ~~options.nPasses,
10 | nFailures = options && ~~options.nFailures,
11 | caseResult = new TestCaseResult(options);
12 | for (i = 0; i < nFailures; i++) {
13 | caseResult.addFailure({}, i * 1000);
14 | }
15 | for (i = 0; i < nPasses; i++) {
16 | caseResult.addSuccess({}, i * 1000);
17 | }
18 | return caseResult;
19 | }
20 |
21 | casper.test.begin('TestSuiteResult() basic tests', 8, function(test) {
22 | var suiteResult = new TestSuiteResult();
23 | test.assertEquals(suiteResult.constructor.name, 'Array', 'TestSuiteResult() is derived from Array');
24 | test.assertEquals(suiteResult.countTotal(), 0);
25 | test.assertEquals(suiteResult.countFailed(), 0);
26 | test.assertEquals(suiteResult.countPassed(), 0);
27 | test.assertEquals(suiteResult.getAllFailures(), []);
28 | test.assertEquals(suiteResult.getAllPasses(), []);
29 | test.assertEquals(suiteResult.getAllResults(), []);
30 | test.assertEquals(suiteResult.calculateDuration(), 0);
31 | test.done();
32 | });
33 |
34 | casper.test.begin('TestSuiteResult() accumulation tests', 7, function(test) {
35 | var suiteResult = new TestSuiteResult();
36 | suiteResult.push(generateCaseResult({
37 | name: 'foo',
38 | file: '/tmp/foo',
39 | nPasses: 4,
40 | nFailures: 1
41 | }));
42 | suiteResult.push(generateCaseResult({
43 | name: 'bar',
44 | file: '/tmp/bar',
45 | nPasses: 3,
46 | nFailures: 0
47 | }));
48 | test.assertEquals(suiteResult.countTotal(), 8);
49 | test.assertEquals(suiteResult.countFailed(), 1);
50 | test.assertEquals(suiteResult.countPassed(), 7);
51 | test.assertEquals(suiteResult.getAllFailures().length, 1);
52 | test.assertEquals(suiteResult.getAllPasses().length, 7);
53 | test.assertEquals(suiteResult.getAllResults().length, 8);
54 | test.assertEquals(suiteResult.calculateDuration(), 9000);
55 | test.done();
56 | });
57 |
--------------------------------------------------------------------------------
/docs/writing_modules.rst:
--------------------------------------------------------------------------------
1 | .. _writing_modules:
2 |
3 | .. index:: Modules, Modules, Custom module
4 |
5 | Writing CasperJS modules
6 | ========================
7 |
8 | As of 1.1, CasperJS relies on PhantomJS' native ``require()`` function internally though it had to be patched in order to allow requiring casper modules using their full name, eg. ``require('casper')``.
9 |
10 | So if you plan to write your own modules and use casperjs' ones from them, be sure to call the ``patchRequire()`` function::
11 |
12 | // my module, stored in universe.js
13 | // patching phantomjs' require()
14 | var require = patchRequire(require);
15 |
16 | // now you're ready to go
17 | var utils = require('utils');
18 | var magic = 42;
19 | exports.answer = function() {
20 | return utils.format("it's %d", magic);
21 | };
22 |
23 | .. warning::
24 |
25 | When using CoffeeScript ``global.require`` must be passed to ``patchRequire()`` instead of just ``require``::
26 |
27 | require = patchRequire global.require
28 |
29 | utils = require 'utils'
30 | magic = 42
31 | exports.answer = ->
32 | utils.format "it's ${magic}"
33 |
34 | From your root casper script::
35 |
36 | var universe = require('./universe');
37 | console.log(universe.answer()); // prints "It's 42"
38 |
39 | .. versionadded:: 1.1.
40 |
41 | .. hint::
42 |
43 | CasperJS allows using nodejs modules installed through npm_. Note that since CasperJS uses it's own JavaScript environment, npm modules that use node-specific features will not work under CasperJS.
44 |
45 | As an example, let's install the underscore_ library:
46 |
47 | .. _npm: https://npmjs.org/
48 | .. _underscore: http://underscorejs.org/
49 |
50 | .. code-block:: text
51 |
52 | $ npm install underscore
53 |
54 |
55 | Then, ``require`` it like you would with any other nodejs compliant module::
56 |
57 | //npm-underscore-test.js
58 | var _ = require('underscore');
59 | var casper = require('casper').create();
60 | var urls = _.uniq([
61 | 'http://google.com/',
62 | 'http://docs.casperjs.org/',
63 | 'http://google.com/'
64 | ]);
65 |
66 | casper.start().eachThen(urls, function(response) {
67 | this.thenOpen(response.data, function(response) {
68 | this.echo(this.getTitle());
69 | });
70 | });
71 |
72 | casper.run();
73 |
74 |
75 | Finally, you’ll probably get something like this:
76 |
77 | .. code-block:: text
78 |
79 | $ casperjs npm-underscore-test.js
80 | Google
81 | CasperJS documentation | CasperJS 1.1.0-DEV documentation
82 |
83 |
84 |
--------------------------------------------------------------------------------
/tests/site/area.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Move to Click Position
6 |
47 |
48 |
49 |
50 |
53 |
54 |
57 |
58 |
59 |
97 |
98 |
99 |
--------------------------------------------------------------------------------
/modules/http.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * Casper is a navigation utility for PhantomJS.
3 | *
4 | * Documentation: http://casperjs.org/
5 | * Repository: http://github.com/casperjs/casperjs
6 | *
7 | * Copyright (c) 2011-2012 Nicolas Perriault
8 | *
9 | * Part of source code is Copyright Joyent, Inc. and other Node contributors.
10 | *
11 | * Permission is hereby granted, free of charge, to any person obtaining a
12 | * copy of this software and associated documentation files (the "Software"),
13 | * to deal in the Software without restriction, including without limitation
14 | * the rights to use, copy, modify, merge, publish, distribute, sublicense,
15 | * and/or sell copies of the Software, and to permit persons to whom the
16 | * Software is furnished to do so, subject to the following conditions:
17 | *
18 | * The above copyright notice and this permission notice shall be included
19 | * in all copies or substantial portions of the Software.
20 | *
21 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
24 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27 | * DEALINGS IN THE SOFTWARE.
28 | *
29 | */
30 |
31 | var require = patchRequire(require);
32 | var utils = require('utils');
33 |
34 | /*
35 | * Building an Array subclass
36 | */
37 | function responseHeaders(){}
38 | responseHeaders.prototype = [];
39 |
40 | /**
41 | * Retrieves a given header based on its name
42 | *
43 | * @param String name A case-insensitive response header name
44 | * @return mixed A header string or `null` if not found
45 | */
46 | responseHeaders.prototype.get = function get(name){
47 | "use strict";
48 | var headerValue = null;
49 | name = name.toLowerCase();
50 | this.some(function(header){
51 | if (header.name.toLowerCase() === name){
52 | headerValue = header.value;
53 | return true;
54 | }
55 | });
56 | return headerValue;
57 | };
58 |
59 | /**
60 | * Augments the response with proper prototypes.
61 | *
62 | * @param Mixed response Phantom response or undefined (generally with local files)
63 | * @return Object Augmented response
64 | */
65 | exports.augmentResponse = function(response) {
66 | "use strict";
67 | if (!utils.isHTTPResource(response)) {
68 | return;
69 | }
70 | response.headers.__proto__ = responseHeaders.prototype;
71 | return response;
72 | };
73 |
--------------------------------------------------------------------------------
/samples/bbcshots.js:
--------------------------------------------------------------------------------
1 | /*eslint strict:0*/
2 | /*global CasperError, console*/
3 |
4 | /**
5 | * Create a mosaic image from all headline photos on BBC homepage
6 | */
7 | var casper = require("casper").create();
8 | var nbLinks = 0;
9 | var currentLink = 1;
10 | var images = [];
11 | var buildPage, next;
12 |
13 | // helper to hide some element from remote DOM
14 | casper.hide = function(selector) {
15 | this.evaluate(function(selector) {
16 | document.querySelector(selector).style.display = "none";
17 | }, selector);
18 | };
19 |
20 | casper.start("http://www.bbc.co.uk/", function() {
21 | nbLinks = this.evaluate(function() {
22 | return __utils__.findAll('#promo2_carousel_items_items li').length;
23 | });
24 | this.echo(nbLinks + " items founds");
25 | // hide navigation arrows
26 | this.hide(".nav_left");
27 | this.hide(".nav_right");
28 | this.mouse.move("#promo2_carousel");
29 | });
30 |
31 | casper.waitUntilVisible(".autoplay.nav_pause", function() {
32 | this.echo("Moving over pause button");
33 | this.mouse.move(".autoplay.nav_pause");
34 | this.click(".autoplay.nav_pause");
35 | this.echo("Clicked on pause button");
36 | this.waitUntilVisible(".autoplay.nav_play", function() {
37 | this.echo("Carousel has been paused");
38 | // hide play button
39 | this.hide(".autoplay");
40 | });
41 | });
42 |
43 | // Capture carrousel area
44 | next = function() {
45 | var image;
46 | image = "bbcshot" + currentLink + ".png";
47 | images.push(image);
48 | this.echo("Processing image " + currentLink);
49 | this.captureSelector(image, '.carousel_viewport');
50 | if (currentLink < nbLinks) {
51 | this.click(".carousel_itemList_li[rel='" + currentLink + "']");
52 | this.wait(1000, function() {
53 | this.then(next);
54 | currentLink++;
55 | });
56 | } else {
57 | this.then(buildPage);
58 | }
59 | };
60 |
61 | // Building resulting page and image
62 | buildPage = function() {
63 | var fs, pageHtml;
64 | this.echo("Build result page");
65 | fs = require("fs");
66 | this.viewport(624, 400);
67 | pageHtml = "";
68 | images.forEach(function(image) {
69 | pageHtml += " ";
70 | });
71 | pageHtml += "";
72 | fs.write("result.html", pageHtml, 'w');
73 | this.thenOpen("file://" + fs.workingDirectory + "/result.html", function() {
74 | this.echo("Resulting image saved to result.png");
75 | this.capture("result.png");
76 | });
77 | };
78 |
79 | casper.then(next);
80 |
81 | casper.run();
82 |
--------------------------------------------------------------------------------
/tests/site/mouse-events.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CasperJS test mouse events
6 |
7 |
8 |
9 | test
10 | test
11 | test
12 | test
13 | test
14 | test
15 | test
16 | test
17 |
22 |
58 |
59 |
60 |
--------------------------------------------------------------------------------
/tests/suites/casper/mouseevents.js:
--------------------------------------------------------------------------------
1 | /*eslint strict:0, max-statements:0*/
2 | casper.on('remote.message',function(e){
3 | console.log(e);
4 | });
5 |
6 | casper.test.begin('mouseEvent() tests', 20, function(test) {
7 | casper.start('tests/site/mouse-events.html', function() {
8 | test.assert(this.mouseEvent('mousedown', '#test1'), 'Casper.mouseEvent() can dispatch a mousedown event');
9 | test.assert(this.mouseEvent('mousedown', '#test2'), 'Casper.mouseEvent() can dispatch a mousedown event handled by unobstrusive js');
10 | test.assert(this.mouseEvent('mouseup', '#test3'), 'Casper.mouseEvent() can dispatch a mouseup event');
11 | test.assert(this.mouseEvent('mouseup', '#test4'), 'Casper.mouseEvent() can dispatch a mouseup event handled by unobstrusive js');
12 | test.assert(this.mouseEvent('mouseover', '#test5'), 'Casper.mouseEvent() can dispatch a mouseover event');
13 | test.assert(this.mouseEvent('mouseover', '#test6'), 'Casper.mouseEvent() can dispatch a mouseover event handled by unobstrusive js');
14 | test.assert(this.mouseEvent('mouseout', '#test7'), 'Casper.mouseEvent() can dispatch a mouseout event');
15 | test.assert(this.mouseEvent('mouseout', '#test8'), 'Casper.mouseEvent() can dispatch a mouseout event handled by unobstrusive js');
16 | test.assertFalsy(this.mouseEvent('click', '#test9'), 'Casper.mouseEvent() can dispatch a click event on an hidden element');
17 | test.assertFalsy(this.mouseEvent('click', '#test10'), 'Casper.mouseEvent() can dispatch a click event handled by unobstrusive js on an hidden element ');
18 | });
19 |
20 | casper.then(function() {
21 | var results = this.getGlobal('results');
22 | test.assert(results.test1, 'Casper.mouseEvent() triggered mousedown');
23 | test.assert(results.test2, 'Casper.mouseEvent() triggered mousedown via unobstrusive js');
24 | test.assert(results.test3, 'Casper.mouseEvent() triggered mouseup');
25 | test.assert(results.test4, 'Casper.mouseEvent() triggered mouseup via unobstrusive js');
26 | test.assert(results.test5, 'Casper.mouseEvent() triggered mouseover');
27 | test.assert(results.test6, 'Casper.mouseEvent() triggered mouseover via unobstrusive js');
28 | test.assert(results.test7, 'Casper.mouseEvent() triggered mouseout');
29 | test.assert(results.test8, 'Casper.mouseEvent() triggered mouseout via unobstrusive js');
30 | test.assertFalsy(results.test9, 'Casper.mouseEvent() triggered click on an hidden element');
31 | test.assertFalsy(results.test10, 'Casper.mouseEvent() triggered click on an hidden element via unobstrusive js');
32 | });
33 |
34 | casper.run(function() {
35 | test.done();
36 | });
37 | });
38 |
--------------------------------------------------------------------------------
/tests/selftest.js:
--------------------------------------------------------------------------------
1 |
2 | var require = patchRequire(require);
3 | var colorizer = require('colorizer').create('Colorizer');
4 | var fs = require('fs');
5 | var utils = require('utils');
6 | var server = require('webserver').create();
7 | var service;
8 | var testServerPort = 54321;
9 |
10 | var contentTypes = {
11 | html: {type: 'text/html', binMode: false},
12 | js: {type: 'application/javascript', binMode: false},
13 | json: {type: 'application/json', binMode: false},
14 | txt: {type: 'text/plain', binMode: false},
15 | png: {type: 'image/png', binMode: true},
16 | notype: {type: null, binMode: false},
17 | _default: {type: 'application/octet-stream', binMode: true}
18 | };
19 | var extensionRE = /\.([a-zA-Z]*)$/;
20 |
21 | function info(message) {
22 | "use strict";
23 | console.log(colorizer.colorize('INFO', 'INFO_BAR') + ' ' + message);
24 | }
25 |
26 | service = server.listen(testServerPort, function(request, response) {
27 | "use strict";
28 | /*eslint max-statements:0*/
29 | var requestPath = request.url;
30 | if (requestPath.indexOf('?') !== -1) {
31 | requestPath = request.url.split('?')[0];
32 | }
33 | var pageFile = fs.pathJoin(phantom.casperPath, requestPath);
34 | if (!fs.exists(pageFile) || !fs.isFile(pageFile)) {
35 | response.statusCode = 404;
36 | console.log(utils.format('Test server url not found: %s (file: %s)', request.url, pageFile), "warning");
37 | response.write("404 - NOT FOUND");
38 | } else {
39 | var headers = {};
40 | var binMode;
41 |
42 | var extension = extensionRE.exec(pageFile);
43 | extension = extension && extension[1];
44 | var contentType = contentTypes[extension] ||
45 | contentTypes._default;
46 |
47 | if (contentType.type) {
48 | headers['Content-Type'] = contentType.type;
49 | }
50 | binMode = contentType.binMode;
51 |
52 | response.writeHead(200, headers);
53 |
54 | if (binMode) {
55 | response.write(fs.read(pageFile, 'b'));
56 | }
57 | else {
58 | response.write(fs.read(pageFile));
59 | }
60 | }
61 | response.close();
62 | });
63 |
64 | // overriding Casper.open to prefix all test urls
65 | casper.setFilter('open.location', function(location) {
66 | "use strict";
67 | if (/^file/.test(location)) {
68 | return location;
69 | }
70 | if (!/^http/.test(location)) {
71 | return utils.format('http://localhost:%d/%s', testServerPort, location);
72 | }
73 | return location;
74 | });
75 |
76 | // test suites completion listener
77 | casper.test.on('tests.complete', function() {
78 | "use strict";
79 | server.close();
80 | });
81 |
--------------------------------------------------------------------------------
/tests/suites/casper/hooks.js:
--------------------------------------------------------------------------------
1 | /*eslint strict:0*/
2 | casper.test.begin('onStepComplete() hook tests', 1, function(test) {
3 | var stepResults = [];
4 | casper.options.onStepComplete = function(self, stepResult) {
5 | stepResults.push(stepResult);
6 | };
7 | casper.start('tests/site/index.html', function() {
8 | return 'ok';
9 | });
10 | casper.run(function() {
11 | test.assert(stepResults.indexOf('ok') > -1,
12 | 'Casper.options.onStepComplete() is called on step complete');
13 | this.options.onStepComplete = undefined;
14 | test.done();
15 | });
16 | });
17 |
18 | casper.test.begin('onResourceRequested() & onResourceReceived() hook tests', 6, function(test) {
19 | var requests = [], responses = [];
20 | casper.options.onResourceRequested = function(self, request) {
21 | requests.push(request);
22 | };
23 | casper.options.onResourceReceived = function(self, response) {
24 | responses.push(response);
25 | };
26 | casper.start('tests/site/index.html', function() {
27 | test.assert(requests.some(function(request) {
28 | return (/index\.html$/).test(request.url);
29 | }), 'onResourceRequested() receives page requests');
30 | test.assert(requests.some(function(request) {
31 | return (/phantom\.png$/).test(request.url);
32 | }), 'onResourceRequested() receives image requests');
33 | test.assert(responses.some(function(response) {
34 | return response.stage === 'start' && (/index\.html$/).test(response.url);
35 | }), 'onResourceReceived() receives page response on load start');
36 | test.assert(responses.some(function(response) {
37 | return response.stage === 'end' && (/index\.html$/).test(response.url);
38 | }), 'onResourceReceived() receives page response on load end');
39 | test.assert(responses.some(function(response) {
40 | return response.stage === 'start' && (/phantom\.png$/).test(response.url);
41 | }), 'onResourceReceived() receives image response on load start');
42 | test.assert(responses.some(function(response) {
43 | return response.stage === 'end' && (/phantom\.png$/).test(response.url);
44 | }), 'onResourceReceived() receives image response on load end');
45 | });
46 | casper.run(function() {
47 | this.options.onResourceReceived = this.options.onResourceRequested = undefined;
48 | test.done();
49 | });
50 | });
51 |
52 | casper.test.begin('onAlert() hook tests', 1, function(test) {
53 | var message;
54 | casper.options.onAlert = function(self, msg) {
55 | message = msg;
56 | };
57 | casper.start('tests/site/alert.html', function() {
58 | test.assertEquals(message, 'plop', 'Casper.options.onAlert() can intercept an alert message');
59 | });
60 | casper.run(function() {
61 | this.options.onAlert = null;
62 | test.done();
63 | });
64 | });
65 |
--------------------------------------------------------------------------------
/tests/suites/http_status.js:
--------------------------------------------------------------------------------
1 | /*eslint strict:0*/
2 | /**
3 | * Special test server to test for HTTP status codes
4 | *
5 | */
6 | var fs = require('fs');
7 | var utils = require('utils');
8 |
9 | casper.test.begin("HTTP status code handling", 163, {
10 | setUp: function(test) {
11 | this.server = require('webserver').create();
12 | this.server.listen(8090, function (request, response) {
13 | response.statusCode = parseInt(/^\/(\d+)$/.exec(request.url)[1], 10);
14 | response.write("");
15 | response.close();
16 | });
17 | var isGecko = (phantom.casperEngine === 'slimerjs');
18 |
19 | this.testCodes = [
20 | 100, 101, 200, 201, 202, 203, 204, 205, 206, 207, 210,
21 | 300, 301, 302, 303, 304, 305, 307, 310
22 | ];
23 | if (!isGecko) {
24 | // it seems that the network layer of Gecko does not process these response
25 | this.testCodes.push(102);
26 | this.testCodes.push(118);
27 | }
28 |
29 | if (utils.ltVersion(phantom.version, '1.9.0') ||
30 | utils.gteVersion(phantom.version, '1.9.2') ||
31 | isGecko) {
32 | // https://github.com/ariya/phantomjs/issues/11163
33 | this.testCodes = this.testCodes.concat([
34 | 400, 401, 402, 403, 404, 405, 406, 407, 409, 410, 411, 412, 413,
35 | 414, 415, 416, 417, 418, 422, 423, 424, 425, 426, 449, 450,
36 | 500, 501, 502, 503, 504, 505, 507, 509
37 | ]);
38 | if (!isGecko) {
39 | // it seems that the network layer of Gecko has a different
40 | // behavior for 408 than PhantomJS's webkit
41 | this.testCodes.push(408);
42 | }
43 | }
44 | if ((this.testCodes.length * 3) < 165 ) {
45 | test.skip(163 - (this.testCodes.length * 3 - 2) );
46 | }
47 | },
48 |
49 | tearDown: function() {
50 | this.server.close();
51 | },
52 |
53 | test: function(test) {
54 | casper.start();
55 |
56 | // file protocol
57 | casper.thenOpen('file://' + phantom.casperPath + '/tests/site/index.html', function() {
58 | this.test.assertHttpStatus(null, 'file:// protocol does not set a HTTP status');
59 | });
60 |
61 | casper.each(this.testCodes, function(self, code) {
62 | if (code === 100) {
63 | // HTTP 100 is CONTINUE, so don't expect a terminated response
64 | return;
65 | }
66 | this.thenOpen('http://localhost:8090/' + code, function(resource) {
67 | test.assertEquals(resource.status, code,
68 | 'Status is stored in resource.status');
69 | test.assertEquals(this.currentHTTPStatus, code,
70 | 'Status is stored in casper.currentHTTPStatus');
71 | test.assertHttpStatus(code, utils.format('HTTP %d handled' , code));
72 | });
73 | });
74 |
75 | casper.run(function() {
76 | this.test.done();
77 | });
78 | }
79 | });
80 |
--------------------------------------------------------------------------------
/rpm/casperjs.spec:
--------------------------------------------------------------------------------
1 | %define name casperjs
2 | %if "%{_version}"
3 | %define version %{_version}
4 | %else
5 | %define version 1.0
6 | %endif
7 | %define release 1
8 | %define prefix /usr
9 |
10 | %define mybuilddir %{_builddir}/%{name}-%{version}-root
11 |
12 | Summary: open source navigation scripting & testing utility written in Javascript
13 | Name: %{name}
14 | Version: %{version}
15 | License: BSD
16 | Release: %{release}
17 | Packager: Jan Schaumann
18 | Group: Utilities/Misc
19 | Source: %{name}-%{version}.tar.gz
20 | BuildRoot: /tmp/%{name}-%{version}-root
21 |
22 | Requires: phantomjs
23 |
24 | %description
25 | CasperJS is an open source navigation scripting & testing utility written
26 | in Javascript and based on PhantomJS. It eases the process of defining a
27 | full navigation scenario and provides useful high-level functions, methods
28 | & syntactic sugar for doing common tasks
29 |
30 | %prep
31 | %setup -q
32 |
33 | %install
34 | mkdir -p %{mybuilddir}%{prefix}/bin
35 | mkdir -p %{mybuilddir}%{prefix}/share/%{name}/bin
36 | mkdir -p %{mybuilddir}%{prefix}/share/%{name}/modules
37 | mkdir -p %{mybuilddir}%{prefix}/share/%{name}/samples
38 | mkdir -p %{mybuilddir}%{prefix}/share/%{name}/tests
39 |
40 | cp bin/%{name} %{mybuilddir}%{prefix}/share/%{name}/bin/
41 | ln -s %{prefix}/share/%{name}/bin/%{name} %{mybuilddir}%{prefix}/bin/%{name}
42 | cp bin/bootstrap.js %{mybuilddir}%{prefix}/share/%{name}/bin/
43 | # Yes, this tool needs this file in the 'bin' directory.
44 | cp bin/usage.txt %{mybuilddir}%{prefix}/share/%{name}/bin/
45 | cp CHANGELOG.md %{mybuilddir}%{prefix}/share/%{name}/
46 | cp CONTRIBUTING.md %{mybuilddir}%{prefix}/share/%{name}/
47 | cp CONTRIBUTORS.md %{mybuilddir}%{prefix}/share/%{name}/
48 | cp LICENSE.md %{mybuilddir}%{prefix}/share/%{name}/
49 | cp README.md %{mybuilddir}%{prefix}/share/%{name}/
50 | cp package.json %{mybuilddir}%{prefix}/share/%{name}/
51 | cp -R modules/* %{mybuilddir}%{prefix}/share/%{name}/modules/
52 | cp -R samples/* %{mybuilddir}%{prefix}/share/%{name}/samples/
53 | cp -R tests/* %{mybuilddir}%{prefix}/share/%{name}/tests/
54 |
55 | %files
56 | %defattr(0444,root,root)
57 | %attr(0555,root,root)%{prefix}/bin/%{name}
58 | %attr(0555,root,root)%{prefix}/share/%{name}/bin/%{name}
59 | %attr(0555,root,root)%{prefix}/share/%{name}/bin/bootstrap.js
60 | %{prefix}/share/%{name}/bin/usage.txt
61 | %{prefix}/share/%{name}/CHANGELOG.md
62 | %{prefix}/share/%{name}/CONTRIBUTING.md
63 | %{prefix}/share/%{name}/CONTRIBUTORS.md
64 | %{prefix}/share/%{name}/LICENSE.md
65 | %{prefix}/share/%{name}/README.md
66 | %{prefix}/share/%{name}/package.json
67 | %{prefix}/share/%{name}/modules/*
68 | %{prefix}/share/%{name}/samples/*
69 | %{prefix}/share/%{name}/tests/*
70 |
71 | %changelog
72 | * Fri Nov 15 2013 Yasuo Ohgaki
73 | - update spec for master and other branches
74 |
75 | * Mon Dec 24 2012 Nicolas Perriault
76 | - removed 'injector.js' module
77 |
78 | * Mon Dec 10 2012 Jan Schaumann
79 | - include 'tests'
80 |
81 | * Mon Nov 26 2012 Jan Schaumann
82 | - first rpm version
83 |
--------------------------------------------------------------------------------
/tests/suites/casper/keys.js:
--------------------------------------------------------------------------------
1 | /*eslint strict:0*/
2 | /*global CasperError, casper, console, phantom, require*/
3 | var utils = require('utils');
4 |
5 | casper.test.begin('sendKeys() tests', 4, function(test) {
6 | casper.start('tests/site/form.html', function() {
7 | this.sendKeys('input[name="email"]', 'duke@nuk.em');
8 | this.sendKeys('input[name="language"]', 'fr', {keepFocus: true});
9 | this.click('#autocomplete li:first-child');
10 | this.sendKeys('textarea', "Damn, I’m looking good.");
11 | var values = this.getFormValues('form[action="result.html"]');
12 | test.assertEquals(values.email, 'duke@nuk.em',
13 | 'Casper.sendKeys() sends keys to given input');
14 | test.assertEquals(values.language, 'french',
15 | 'Casper.sendKeys() sends keys to given input and keeps focus afterweards');
16 | test.assertEquals(values.content, "Damn, I’m looking good.",
17 | 'Casper.sendKeys() sends keys to given textarea');
18 |
19 | this.sendKeys('input[name="notype"]', "I have no type.");
20 | values = this.getFormValues('form#no-type-test-form');
21 | test.assertEquals(values.notype, "I have no type.",
22 | 'Casper.sendKeys() sends keys to given input without type attribute');
23 | }).run(function() {
24 | test.done();
25 | });
26 | });
27 |
28 | casper.test.begin('sendKeys() works on content-editable elements', 1, function(test) {
29 | casper.start('tests/site/elementattribute.html', function() {
30 | this.click('#content-editable-div');
31 | this.sendKeys('#content-editable-div', 'A Clockwork Orange');
32 | }).then(function() {
33 | test.assertSelectorHasText('#content-editable-div','A Clockwork Orange');
34 | }).run(function() {
35 | test.done();
36 | });
37 | });
38 |
39 | if (utils.gteVersion(phantom.version, '1.9.0')) {
40 | casper.test.begin('sendKeys() key modifiers tests', 1, function(test) {
41 | casper.start().then(function() {
42 | this.setContent([
43 | ' ',
44 | ''
47 | ].join(''));
48 | this.sendKeys('input', 'k');
49 | this.sendKeys('input', 'k', {modifiers: "ctrl"});
50 | this.sendKeys('input', 'k', {modifiers: "ctrl+alt"});
51 | test.assertEquals(this.getGlobal('keys'),
52 | [
53 | {code: 107, alt: false, ctrl: false},
54 | {code: 107, alt: false, ctrl: true},
55 | {code: 107, alt: true, ctrl: true}
56 | ], 'sendKeys() uses key modifiers');
57 | }).run(function() {
58 | test.done();
59 | });
60 | });
61 | }
62 |
63 | casper.test.begin('sendKeys() reset option', 1, function(test) {
64 | casper.start('tests/site/form.html', function() {
65 | this.sendKeys('textarea', 'foo');
66 | this.sendKeys('textarea', 'bar', {reset: true});
67 | var values = this.getFormValues('form[action="result.html"]');
68 | test.assertEquals(values.content, "bar");
69 | }).run(function() {
70 | test.done();
71 | });
72 | });
73 |
--------------------------------------------------------------------------------
/docs/_themes/casperjs/addon.html:
--------------------------------------------------------------------------------
1 | Donate
2 |
3 |
4 |
10 |
(ghosts have bills, you know)
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/docs/selectors.rst:
--------------------------------------------------------------------------------
1 | .. _selectors:
2 |
3 | .. index:: selector, DOM, HTML
4 |
5 | =========
6 | Selectors
7 | =========
8 |
9 | CasperJS makes a heavy use of selectors in order to work with the `DOM `_, and can transparently use either `CSS3 `_ or `XPath `_ expressions.
10 |
11 | All the examples below are based on this HTML code:
12 |
13 | .. code-block:: html
14 |
15 |
16 |
17 |
18 |
19 | My page
20 |
21 |
22 | Hello
23 |
24 | one
25 | two
26 | three
27 |
28 |
29 |
30 |
31 |
32 | .. index:: CSS, CSS3
33 |
34 | CSS3
35 | ----
36 |
37 | By default, CasperJS accepts `CSS3 selector strings `_ to check for elements within the DOM.
38 |
39 | To check if the ```` element exists in the example page, you can use::
40 |
41 | var casper = require('casper').create();
42 |
43 | casper.start('http://domain.tld/page.html', function() {
44 | if (this.exists('h1.page-title')) {
45 | this.echo('the heading exists');
46 | }
47 | });
48 |
49 | casper.run();
50 |
51 | Or if you're using the :doc:`testing framework `::
52 |
53 | casper.test.begin('The heading exists', 1, function suite(test) {
54 | casper.start('http://domain.tld/page.html', function() {
55 | test.assertExists('h1.page-title');
56 | }).run(function() {
57 | test.done();
58 | });
59 | });
60 |
61 | Some other convenient testing methods are relying on selectors::
62 |
63 | casper.test.begin('Page content tests', 3, function suite(test) {
64 | casper.start('http://domain.tld/page.html', function() {
65 | test.assertExists('h1.page-title');
66 | test.assertSelectorHasText('h1.page-title', 'Hello');
67 | test.assertVisible('footer');
68 | }).run(function() {
69 | test.done();
70 | });
71 | });
72 |
73 | .. index:: XPath
74 |
75 | XPath
76 | -----
77 |
78 | .. versionadded:: 0.6.8
79 |
80 | You can alternatively use `XPath expressions `_ instead::
81 |
82 | casper.start('http://domain.tld/page.html', function() {
83 | this.test.assertExists({
84 | type: 'xpath',
85 | path: '//*[@class="plop"]'
86 | }, 'the element exists');
87 | });
88 |
89 | To ease the use and reading of XPath expressions, a ``selectXPath`` helper is available from the ``casper`` module::
90 |
91 | var x = require('casper').selectXPath;
92 |
93 | casper.start('http://domain.tld/page.html', function() {
94 | this.test.assertExists(x('//*[@id="plop"]'), 'the element exists');
95 | });
96 |
97 | .. warning::
98 |
99 | The only limitation of XPath use in CasperJS is in the :ref:`casper.fill() ` method when you want to fill **file fields**; PhantomJS natively only allows the use of CSS3 selectors in its `uploadFile method `_, hence this limitation.
100 |
--------------------------------------------------------------------------------
/tests/suites/tester/testcase.js:
--------------------------------------------------------------------------------
1 | /*eslint strict:0, max-statements:0, complexity:0*/
2 |
3 | var TestCaseResult = require('tester').TestCaseResult;
4 |
5 | casper.test.begin('TestCaseResult.constructor() tests', 4, function(test) {
6 | var caseResult1 = new TestCaseResult();
7 | test.assertType(caseResult1.name, "undefined", 'TestCaseResult.constructor() name is undefined by default');
8 | test.assertType(caseResult1.file, "undefined", 'TestCaseResult.constructor() file is undefined by default');
9 | var caseResult2 = new TestCaseResult({name: 'foo', file: '/tmp/foo'});
10 | test.assertEquals(caseResult2.name, "foo", 'TestCaseResult.constructor() can set name');
11 | test.assertEquals(caseResult2.file, "/tmp/foo", 'TestCaseResult.constructor() can set file');
12 | test.done();
13 | });
14 |
15 | casper.test.begin('TestCaseResult.addSuccess() and TestCaseResult.addFailure() tests', 22, function(test) {
16 | var caseResult = new TestCaseResult({name: 'foo', file: '/tmp/foo'});
17 | test.assertEquals(caseResult.assertions, 0, 'test case result counts no assertion by default');
18 | test.assertEquals(caseResult.passed, 0, 'test case result counts no success by default');
19 | test.assertEquals(caseResult.failed, 0, 'test case result counts no failure by default');
20 | test.assertEquals(caseResult.calculateDuration(), 0,
21 | 'TestCaseResult.calculateDuration() computes initial tests duration');
22 | var success = {};
23 | caseResult.addSuccess(success, 1337);
24 | test.assertEquals(caseResult.assertions, 1, 'test case result counts one assertion');
25 | test.assertEquals(caseResult.passed, 1, 'test case result counts one success');
26 | test.assertEquals(caseResult.failed, 0, 'test case result counts no failure');
27 | test.assertEquals(caseResult.passes[0], success, 'TestCaseResult.addSuccess() added a success to the stack');
28 | test.assertEquals(caseResult.passes[0].time, 1337, 'TestCaseResult.addSuccess() added test duration');
29 | test.assertEquals(caseResult.passes[0].suite, 'foo', 'TestCaseResult.addSuccess() added suite name');
30 | test.assertEquals(caseResult.calculateDuration(), 1337,
31 | 'TestCaseResult.calculateDuration() computes tests duration');
32 | var failure = {};
33 | caseResult.addFailure(failure, 42);
34 | test.assertEquals(caseResult.assertions, 2, 'test case result counts two assertions');
35 | test.assertEquals(caseResult.passed, 1, 'test case result counts one success');
36 | test.assertEquals(caseResult.failed, 1, 'test case result counts no failure');
37 | test.assertEquals(caseResult.failures[0], failure, 'TestCaseResult.addFailure() added a failure to the stack');
38 | test.assertEquals(caseResult.failures[0].time, 42, 'TestCaseResult.addFailure() added test duration');
39 | test.assertEquals(caseResult.failures[0].suite, 'foo', 'TestCaseResult.addFailure() added suite name');
40 | test.assertEquals(caseResult.calculateDuration(), 1337 + 42,
41 | 'TestCaseResult.calculateDuration() computes new tests duration');
42 | caseResult.addSuccess({}, 1000);
43 | test.assertEquals(caseResult.assertions, 3, 'test case result counts three assertions');
44 | test.assertEquals(caseResult.passed, 2, 'test case result counts two successes');
45 | test.assertEquals(caseResult.failed, 1, 'test case result counts one failure');
46 | test.assertEquals(caseResult.calculateDuration(), 1337 + 42 + 1000,
47 | 'TestCaseResult.calculateDuration() computes new tests duration');
48 | test.done();
49 | });
50 |
--------------------------------------------------------------------------------
/tests/suites/casper/bypass.js:
--------------------------------------------------------------------------------
1 | /*eslint strict:0*/
2 | casper.test.begin('Casper.bypass() can bypass a step', 2, function(test) {
3 | casper.start();
4 | casper.then(function(){
5 | test.fail("This test should not be executed.");
6 | });
7 | casper.once("step.bypassed", function(step) {
8 | test.pass("step.bypassed event has been catched");
9 | }).bypass(1).run(function() {
10 | test.pass("Step has been bypassed");
11 | test.done();
12 | });
13 | });
14 |
15 | casper.test.begin('Casper.bypass() can bypass multiple steps', 1, function(test) {
16 | casper.start();
17 | casper.then(function() {
18 | test.pass("This test should be executed.");
19 | });
20 | casper.then(function() {
21 | this.bypass(2);
22 | });
23 | casper.then(function() {
24 | test.fail("This test should not be executed.");
25 | });
26 | casper.then(function() {
27 | test.fail("Nor this one.");
28 | });
29 | casper.run(function() {
30 | test.done();
31 | });
32 | });
33 |
34 | casper.test.begin('Casper.thenBypass()', 1, function(test) {
35 | casper.
36 | thenBypass(1).
37 | then(function() {
38 | test.fail("This test should be bypassed.");
39 | }).
40 | then(function() {
41 | test.pass("This test should be executed.");
42 | });
43 |
44 | casper.run(function() {
45 | test.done();
46 | });
47 | });
48 |
49 | casper.test.begin('Casper.thenBypassIf()', 3, function(test) {
50 | casper.
51 | thenBypassIf(true, 1, "Bypass if with function").
52 | then(function() {
53 | test.fail("This test should be bypassed.");
54 | }).
55 | then(function() {
56 | test.pass("This test should be executed.");
57 | }).
58 | thenBypassIf(function() {
59 | return true;
60 | }, 1, "Bypass if with function").
61 | then(function() {
62 | test.fail("This test should be bypassed.");
63 | }).
64 | then(function() {
65 | test.pass("This test should be executed.");
66 | }).
67 | thenBypassIf(function() {
68 | return false;
69 | }, 1, "Do not bypass if with function").
70 | then(function() {
71 | test.pass("This test should be executed.");
72 | });
73 |
74 | casper.run(function() {
75 | test.done();
76 | });
77 | });
78 |
79 | casper.test.begin('Casper.thenBypassUnless()', 3, function(test) {
80 | casper.
81 | thenBypassUnless(false, 1, "Bypass unless with function").
82 | then(function() {
83 | test.fail("This test should be bypassed.");
84 | }).
85 | then(function() {
86 | test.pass("This test should be executed.");
87 | }).
88 | thenBypassUnless(function() {
89 | return false;
90 | }, 1, "Bypass unless with function").
91 | then(function() {
92 | test.fail("This test should be bypassed.");
93 | }).
94 | then(function() {
95 | test.pass("This test should be executed.");
96 | }).
97 | thenBypassUnless(function() {
98 | return true;
99 | }, 1, "Do not bypass unless with function").
100 | then(function() {
101 | test.pass("This test should be executed.");
102 | });
103 |
104 | casper.run(function() {
105 | test.done();
106 | });
107 | });
108 |
--------------------------------------------------------------------------------
/tests/site/click.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CasperJS test click
6 |
7 |
8 | test1
9 | test2
10 | test3
11 | test4
12 | test5
13 | Label with double "quotes"
14 | Label with single 'quotes'
15 |
77 |
78 |
79 |
--------------------------------------------------------------------------------
/tests/clitests/tester/waitFor_timeout.js:
--------------------------------------------------------------------------------
1 | /*eslint strict:0*/
2 |
3 | casper.options.waitTimeout = 500;
4 |
5 | casper.test.begin('waitForSelector fails with expected message', 1, function(test) {
6 | casper.start('../site/waitFor.html');
7 |
8 | casper.waitForSelector('p.nonexistent', function() {
9 | throw new Error('waitForSelector found something it should not have');
10 | });
11 |
12 | casper.run(function() {
13 | test.done();
14 | });
15 | });
16 |
17 | casper.test.begin('waitWhileSelector fails with expected message', 1, function(test) {
18 | casper.start('../site/waitFor.html');
19 |
20 | casper.waitForSelector('#encoded');
21 |
22 | casper.waitWhileSelector('#encoded', function() {
23 | throw new Error('waitWhileSelector thought something got removed when it did not');
24 | });
25 |
26 | casper.run(function() {
27 | test.done();
28 | });
29 | });
30 |
31 | casper.test.begin('waitForSelectorTextChange fails with expected message', 1, function(test) {
32 | casper.start('../site/waitFor.html');
33 |
34 | casper.waitForSelectorTextChange('#encoded', function() {
35 | throw new Error('waitForSelectorTextChange thought text changed when it did not');
36 | });
37 |
38 | casper.run(function() {
39 | test.done();
40 | });
41 | });
42 |
43 | casper.test.begin('waitUntilVisible fails with expected message', 1, function(test) {
44 | casper.start('../site/waitFor.html');
45 |
46 | casper.waitUntilVisible('p[style]', function() {
47 | throw new Error('waitUntilVisible falsely identified a hidden paragraph');
48 | });
49 |
50 | casper.run(function() {
51 | test.done();
52 | });
53 | });
54 |
55 | casper.test.begin('waitWhileVisible fails with expected message', 1, function(test) {
56 | casper.start('../site/waitFor.html');
57 |
58 | casper.waitWhileVisible('img', function() {
59 | throw new Error('waitWhileVisible thought something disappeared when it did not');
60 | });
61 |
62 | casper.run(function() {
63 | test.done();
64 | });
65 | });
66 |
67 | casper.test.begin('waitForUrl fails with expected message', 1, function(test) {
68 | casper.start('../site/waitFor.html');
69 |
70 | casper.waitForUrl(/github\.com/, function() {
71 | throw new Error('waitForUrl thought we actually navigated to GitHub');
72 | });
73 |
74 | casper.run(function() {
75 | test.done();
76 | });
77 | });
78 |
79 | casper.test.begin('waitForPopup fails with expected message', 1, function(test) {
80 | casper.start('../site/waitFor.html');
81 |
82 | casper.waitForPopup(/foobar/, function() {
83 | throw new Error('waitForPopup found something it should not have');
84 | });
85 |
86 | casper.run(function() {
87 | test.done();
88 | });
89 | });
90 |
91 | casper.test.begin('waitForText fails with expected message', 1, function(test) {
92 | casper.start('../site/waitFor.html');
93 |
94 | casper.waitForText("Lorem ipsum", function() {
95 | throw new Error('waitForText found something it should not have');
96 | });
97 |
98 | casper.run(function() {
99 | test.done();
100 | });
101 | });
102 |
103 | casper.test.begin('waitFor fails with expected message', 1, function(test) {
104 | casper.start('../site/waitFor.html');
105 |
106 | casper.waitFor(function() {
107 | return false
108 | }, function() {
109 | throw new Error('waitFor fasely succeeded');
110 | });
111 |
112 | casper.run(function() {
113 | test.done();
114 | });
115 | });
--------------------------------------------------------------------------------
/docs/modules/colorizer.rst:
--------------------------------------------------------------------------------
1 | .. _colorizer_module:
2 |
3 | .. index:: Colors, colorizer
4 |
5 | ========================
6 | The ``colorizer`` module
7 | ========================
8 |
9 | The ``colorizer`` module contains a ``Colorizer`` class which can generate ANSI colored strings::
10 |
11 | var colorizer = require('colorizer').create('Colorizer');
12 | console.log(colorizer.colorize("Hello World", "INFO"));
13 |
14 | Though most of the times you will use it transparently using the :ref:`Casper.echo() ` method::
15 |
16 | casper.echo('an informative message', 'INFO'); // printed in green
17 | casper.echo('an error message', 'ERROR'); // printed in red
18 |
19 | Skipping CasperJS styling operations
20 | ------------------------------------
21 |
22 | If you wish to skip the whole coloration operation and get uncolored plain text, just set the ``colorizerType`` casper option to ``Dummy``::
23 |
24 | var casper = require('casper').create({
25 | colorizerType: 'Dummy'
26 | });
27 |
28 | casper.echo("Hello", "INFO");
29 |
30 | .. index:: Windows
31 |
32 | .. note::
33 |
34 | That's especially useful if you're using CasperJS on the Windows platform, as there's no support for colored output on this platform.
35 |
36 | .. _colorizer_styles:
37 |
38 | .. index:: Printing styles
39 |
40 | Available predefined styles
41 | ---------------------------
42 |
43 | Available predefined styles are:
44 |
45 | - ``ERROR``: white text on red background
46 | - ``INFO``: green text
47 | - ``TRACE``: green text
48 | - ``PARAMETER``: cyan text
49 | - ``COMMENT``: yellow text
50 | - ``WARNING``: red text
51 | - ``GREEN_BAR``: white text on green background
52 | - ``RED_BAR``: white text on red background
53 | - ``INFO_BAR``: cyan text
54 | - ``WARN_BAR``: white text on orange background
55 |
56 | Here's a sample output of what it can look like:
57 |
58 | .. figure:: ../_static/images/colorizer.png
59 | :align: center
60 |
61 | ``colorize()``
62 | -------------------------------------------------------------------------------
63 |
64 | **Signature:** ``colorize(String text, String styleName)``
65 |
66 | Computes a colored version of the provided text string using a given predefined style::
67 |
68 | var colorizer = require('colorizer').create();
69 | console.log(colorizer.colorize("I'm a red error", "ERROR"));
70 |
71 | .. note::
72 |
73 | Most of the time you won't have to use a ``Colorizer`` instance directly as CasperJS provides all the necessary methods.
74 |
75 | See the list of the :ref:`predefined styles available `.
76 |
77 | ``format()``
78 | -------------------------------------------------------------------------------
79 |
80 | **Signature:** ``format(String text, Object style)``
81 |
82 | Formats a text string using the provided style definition. A style definition is a standard javascript ``Object`` instance which can define the following properties:
83 |
84 | - String ``bg``: background color name
85 | - String ``fg``: foreground color name
86 | - Boolean ``bold``: apply bold formatting
87 | - Boolean ``underscore``: apply underline formatting
88 | - Boolean ``blink``: apply blink formatting
89 | - Boolean ``reverse``: apply reverse formatting
90 | - Boolean ``conceal``: apply conceal formatting
91 |
92 | .. note::
93 |
94 | Available color names are ``black``, ``red``, ``green``, ``yellow``, ``blue``, ``magenta``, ``cyan`` and ``white``::
95 |
96 | var colorizer = require('colorizer').create();
97 | colorizer.format("We all live in a yellow submarine", {
98 | bg: 'yellow',
99 | fg: 'blue',
100 | bold: true
101 | });
102 |
103 |
--------------------------------------------------------------------------------