Commit 6034ce18 6034ce18de6206892c671bfb148d662039a42de5 by Nicolas Perriault

local docs - fixes #393

1 parent 354aed31
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
1 CasperJS Sphinx Documentation
2 =============================
3
4 Sphinx documentation for [CasperJS](http://casperjs.org/) 1.1-DEV and future
5 versions. Work in progress.
1 - credits jeremy (logo)
No preview for this file type
1 <h3>Donate</h3>
2 <div class="donate">
3 <div class="paypal">
4 <form action="https://www.paypal.com/cgi-bin/webscr" method="post">
5 <input type="hidden" name="cmd" value="_s-xclick">
6 <input type="hidden" name="encrypted" value="-----BEGIN PKCS7-----MIIHRwYJKoZIhvcNAQcEoIIHODCCBzQCAQExggEwMIIBLAIBADCBlDCBjjELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MRQwEgYDVQQKEwtQYXlQYWwgSW5jLjETMBEGA1UECxQKbGl2ZV9jZXJ0czERMA8GA1UEAxQIbGl2ZV9hcGkxHDAaBgkqhkiG9w0BCQEWDXJlQHBheXBhbC5jb20CAQAwDQYJKoZIhvcNAQEBBQAEgYC4JCGS/3BUKEbRk75JLTu8saEZukn/6Zl5RMoVI55A2wpXdaYcILRy3L7CC4Exu9QaUzHTqQY5livIcptZaOM+aJYYr4ltJbyRW1hvFfrp0ZKMEgUuaU3m9+KQl4kzF9mRUIb5fwTd2j0FfEOllIDYLhEs6sCf39iI8yNeHsuTqjELMAkGBSsOAwIaBQAwgcQGCSqGSIb3DQEHATAUBggqhkiG9w0DBwQIHb+LDTLRE8+AgaD85VPtS5//ZnqYKJMBxlWxI6ob8L8Zk71t9NAwDY3YB3phdkyYSQtax1QxSYz1zFdNlaN5+zlFVg3chctbR6W/kC1sf4hI+AVRm9JlwYKdPOE2FOescC7QuqwAiCZlTfdejznoE0B3aVfq4OMx2k0STtVv3Ld9prW57EtMZ7xDXIW5ss62IWpsBY8eW2VPbX/Xy8TncrpDLHzJ67OKmj/KoIIDhzCCA4MwggLsoAMCAQICAQAwDQYJKoZIhvcNAQEFBQAwgY4xCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEUMBIGA1UEChMLUGF5UGFsIEluYy4xEzARBgNVBAsUCmxpdmVfY2VydHMxETAPBgNVBAMUCGxpdmVfYXBpMRwwGgYJKoZIhvcNAQkBFg1yZUBwYXlwYWwuY29tMB4XDTA0MDIxMzEwMTMxNVoXDTM1MDIxMzEwMTMxNVowgY4xCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEUMBIGA1UEChMLUGF5UGFsIEluYy4xEzARBgNVBAsUCmxpdmVfY2VydHMxETAPBgNVBAMUCGxpdmVfYXBpMRwwGgYJKoZIhvcNAQkBFg1yZUBwYXlwYWwuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDBR07d/ETMS1ycjtkpkvjXZe9k+6CieLuLsPumsJ7QC1odNz3sJiCbs2wC0nLE0uLGaEtXynIgRqIddYCHx88pb5HTXv4SZeuv0Rqq4+axW9PLAAATU8w04qqjaSXgbGLP3NmohqM6bV9kZZwZLR/klDaQGo1u9uDb9lr4Yn+rBQIDAQABo4HuMIHrMB0GA1UdDgQWBBSWn3y7xm8XvVk/UtcKG+wQ1mSUazCBuwYDVR0jBIGzMIGwgBSWn3y7xm8XvVk/UtcKG+wQ1mSUa6GBlKSBkTCBjjELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MRQwEgYDVQQKEwtQYXlQYWwgSW5jLjETMBEGA1UECxQKbGl2ZV9jZXJ0czERMA8GA1UEAxQIbGl2ZV9hcGkxHDAaBgkqhkiG9w0BCQEWDXJlQHBheXBhbC5jb22CAQAwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQCBXzpWmoBa5e9fo6ujionW1hUhPkOBakTr3YCDjbYfvJEiv/2P+IobhOGJr85+XHhN0v4gUkEDI8r2/rNk1m0GA8HKddvTjyGw/XqXa+LSTlDYkqI8OwR8GEYj4efEtcRpRYBxV8KxAW93YDWzFGvruKnnLbDAF6VR5w/cCMn5hzGCAZowggGWAgEBMIGUMIGOMQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExFjAUBgNVBAcTDU1vdW50YWluIFZpZXcxFDASBgNVBAoTC1BheVBhbCBJbmMuMRMwEQYDVQQLFApsaXZlX2NlcnRzMREwDwYDVQQDFAhsaXZlX2FwaTEcMBoGCSqGSIb3DQEJARYNcmVAcGF5cGFsLmNvbQIBADAJBgUrDgMCGgUAoF0wGAYJKoZIhvcNAQkDMQsGCSqGSIb3DQEHATAcBgkqhkiG9w0BCQUxDxcNMTIwNjI0MTUzOTU1WjAjBgkqhkiG9w0BCQQxFgQUCTlRbQ9Lu+bilBvGXOco0qlRC/8wDQYJKoZIhvcNAQEBBQAEgYBVibaMfUxJXJkA636MBqV4iWXc/F070Tsov5/kALg++/rD5qmH5MV6U8X0H8V1bCFZMBpTtLbCQ9xgeMjaK1gaCrvUw0503tBnvuPDz4bS1dspNHE9boiBJdN5vNZGqxXKij8CgKBeHYmcyCKjywHyUfSDADt1vgb7qQ5bOIvbzA==-----END PKCS7-----">
7 <input type="image" src="https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif" border="0" name="submit" alt="Donate" title="Donate">
8 <img alt="" border="0" src="https://www.paypalobjects.com/fr_FR/i/scr/pixel.gif" width="1" height="1">
9 </form>
10 <small>(ghosts have bills, you know)</small>
11 </div>
12 <div class="flattr">
13 <a href="http://flattr.com/thing/586241/CasperJS-a-navigation-scripting-and-testing-utility-for-PhantomJS" class="flattr" target="_blank"><img src="http://api.flattr.com/button/flattr-badge-large.png" alt="Flattr this" title="Flattr this" border="0"></a>
14 </div>
15 </div>
1 {%- extends "basic/layout.html" %}
2 {% block extrahead %}
3 <link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Asap:400,700,400italic,700italic&amp;subset=latin,latin-ext">
4 <link rel="stylesheet" title="Dark theme" href="{{ pathto('_static/casperjs-dark.css', 1) }}">
5 <link rel="alternate stylesheet" title="Light theme" href="{{ pathto('_static/casperjs-light.css', 1) }}">
6 <script type="text/javascript" src="{{ pathto('_static/style-switcher.js', 1) }}"></script>
7 {% endblock extrahead %}
1 {%- if display_toc %}
2 <h3><a href="{{ pathto(master_doc) }}">{{ _('Document Outline') }}</a></h3>
3 {{ toc }}
4 {%- endif %}
1 <h3>Index</h3>
2 <p><a href="{{ pathto('genindex') }}">Thesaurus</a></p>
3
4 {%- if show_source and has_source and sourcename %}
5 <h3>{{ _('This Page') }}</h3>
6 <ul class="this-page-menu">
7 <li><a href="{{ pathto('_sources/' + sourcename, true)|e }}"
8 rel="nofollow">{{ _('Show Source') }}</a></li>
9 {% if display_github %}
10 <li><a href="https://github.com/{{ github_user }}/{{ github_repo }}/blob/{{ github_version }}{{ conf_py_path }}{{ pagename }}.rst">
11 Show on GitHub</a></li>
12 <li><a href="https://github.com/{{ github_user }}/{{ github_repo }}/edit/{{ github_version }}{{ conf_py_path }}{{ pagename }}.rst">
13 Edit on GitHub</a></li>
14 {% endif %}
15 </ul>
16 {%- endif %}
1 /**
2 * http://www.alistapart.com/articles/alternate/
3 *
4 * var cookie = readCookie("style");
5 * var title = cookie ? cookie : getPreferredStyleSheet();
6 * setActiveStyleSheet(title);
7 */
8 (function(exports, $) {
9 function setActiveStyleSheet(title) {
10 var i, a, main;
11 for (i = 0; (a = document.getElementsByTagName("link")[i]); i++) {
12 if (a.getAttribute("rel").indexOf("style") !== -1 && a.getAttribute("title")) {
13 a.disabled = true;
14 if (a.getAttribute("title") === title) {
15 a.disabled = false;
16 }
17 }
18 }
19 }
20 exports.setActiveStyleSheet = setActiveStyleSheet;
21
22 function getActiveStyleSheet() {
23 var i, a;
24 for (i = 0; (a = document.getElementsByTagName("link")[i]); i++) {
25 if (a.getAttribute("rel").indexOf("style") !== -1 && a.getAttribute("title") && !a.disabled) {
26 return a.getAttribute("title");
27 }
28 }
29 return null;
30 }
31 exports.getActiveStyleSheet = getActiveStyleSheet;
32
33 function getPreferredStyleSheet() {
34 var i, a;
35 for (i = 0; (a = document.getElementsByTagName("link")[i]); i++) {
36 if (a.getAttribute("rel").indexOf("style") !== -1 &&
37 a.getAttribute("rel").indexOf("alt") === -1 &&
38 a.getAttribute("title")) {
39 return a.getAttribute("title");
40 }
41 }
42 return null;
43 }
44 exports.getPreferredStyleSheet = getPreferredStyleSheet;
45
46 function createCookie(name, value, days) {
47 var expires = "";
48 if (days) {
49 var date = new Date();
50 date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
51 expires = "; expires=" + date.toGMTString();
52 }
53 document.cookie = name + "=" + value + expires + "; path=/";
54 }
55
56 function readCookie(name) {
57 var nameEQ = name + "=";
58 var ca = document.cookie.split(';');
59 for (var i = 0; i < ca.length; i++) {
60 var c = ca[i];
61 while (c.charAt(0) === ' ') {
62 c = c.substring(1, c.length);
63 }
64 if (c.indexOf(nameEQ) === 0) {
65 return c.substring(nameEQ.length, c.length);
66 }
67 }
68 return null;
69 }
70
71 function createSwitcher() {
72 var $nav = $('.related').find('ul');
73 var styles = $('link').filter(function(i, link){
74 return $(link).attr('rel').indexOf('style') > -1 && $(link).attr('title');
75 }).map(function(i, link) {
76 return $(link).attr('title');
77 });
78 $(styles).each(function(i, style) {
79 var $link = $('<a/>').attr('href', '#')
80 .attr('title', style)
81 .addClass('style-switch')
82 .text(style);
83 $nav.prepend($('<li/>').addClass('right').append($link));
84 });
85 $('.style-switch').bind('click', function(event) {
86 event.preventDefault();
87 setActiveStyleSheet($(this).attr('title'));
88 });
89 }
90
91 exports.onload = function(e) {
92 var cookie = readCookie("style");
93 var title = cookie ? cookie : getPreferredStyleSheet();
94 setActiveStyleSheet(title);
95 createSwitcher();
96 }
97
98 exports.onunload = function(e) {
99 var title = getActiveStyleSheet();
100 createCookie("style", title, 365);
101 }
102
103 var cookie = readCookie("style");
104 var title = cookie ? cookie : getPreferredStyleSheet();
105 setActiveStyleSheet(title);
106 })(window, window.jQuery);
1 [theme]
2 inherit = basic
1 Changelog
2 =========
3
4 The CasperJS changelog is `hosted on github <https://github.com/n1k0/casperjs/blob/master/CHANGELOG.md#casperjs-changelog>`_.
1 .. _cli:
2
3 .. index:: Command line, CLI, PhantomJS, Shell, arguments, options
4
5 ======================
6 Using the command line
7 ======================
8
9 CasperJS ships with a built-in command line parser on top of PhantomJS' one, located in the ``cli`` module; it exposes passed arguments as **positional ones** and **named options**
10
11 But no worries for manipulating the ``cli`` module parsing API, a ``Casper`` instance always contains a ready to use ``cli`` property, allowing easy access of all these parameters.
12
13 Let's consider this simple casper script::
14
15 var casper = require("casper").create();
16
17 casper.echo("Casper CLI passed args:");
18 require("utils").dump(casper.cli.args);
19
20 casper.echo("Casper CLI passed options:");
21 require("utils").dump(casper.cli.options);
22
23 casper.exit();
24
25 .. note::
26
27 Please note the two ``casper-path`` and ``cli`` options; these are passed to the casper script through the ``casperjs`` Python executable.
28
29 Execution results::
30
31 $ casperjs test.js arg1 arg2 arg3 --foo=bar --plop anotherarg
32 Casper CLI passed args: [
33 "arg1",
34 "arg2",
35 "arg3",
36 "anotherarg"
37 ]
38 Casper CLI passed options: {
39 "casper-path": "/Users/niko/Sites/casperjs",
40 "cli": true,
41 "foo": "bar",
42 "plop": true
43 }
44
45 Getting, checking or dropping parameters::
46
47 var casper = require("casper").create();
48 casper.echo(casper.cli.has(0));
49 casper.echo(casper.cli.get(0));
50 casper.echo(casper.cli.has(3));
51 casper.echo(casper.cli.get(3));
52 casper.echo(casper.cli.has("foo"));
53 casper.echo(casper.cli.get("foo"));
54 casper.cli.drop("foo");
55 casper.echo(casper.cli.has("foo"));
56 casper.echo(casper.cli.get("foo"));
57 casper.exit();
58
59 Execution results:
60
61 .. code-block:: text
62
63 $ casperjs test.js arg1 arg2 arg3 --foo=bar --plop anotherarg
64 true
65 arg1
66 true
67 anotherarg
68 true
69 bar
70 false
71 undefined
72
73 .. hint::
74
75 What if you want to check if any arg or option has been passed to your script? Here you go::
76
77 // removing default options passed by the Python executable
78 casper.cli.drop("cli");
79 casper.cli.drop("casper-path");
80
81 if (casper.cli.args.length === 0 && Object.keys(casper.cli.options).length === 0) {
82 casper.echo("No arg nor option passed").exit();
83 }
84
85 `casperjs` native options
86 -------------------------
87
88 .. versionadded:: 1.1
89
90 .. index:: Logging, log levels
91
92 The `casperjs` command has two available options:
93
94 - ``--direct``: to prints out log messages to the console
95 - ``--log-level=[debug|info|warning|error]`` to set the :ref:`logging level <logging>`
96
97 Example:
98
99 .. code-block:: text
100
101 $ casperjs --direct --log-level=debug myscript.js
102
103 Last but not least, you can still use all PhantomJS standard CLI options as you would do with any other phantomjs script:
104
105 .. code-block:: text
106
107 $ casperjs --web-security=no --cookies-file=/tmp/mycookies.txt myscript.js
108
109 .. hint::
110
111 To remember what the native phantomjs available cli options are, run the ``phantomjs --help`` command.
112
113
114 .. index:: Raw values
115
116 Raw parameter values
117 --------------------
118
119 .. versionadded:: 1.0
120
121 By default, the cli object will process every passed argument & cast them to the appropriate detected type; example script::
122
123 var casper = require('casper').create();
124 var utils = require('utils');
125
126 utils.dump(casper.cli.get('foo'));
127
128 casper.exit();
129
130 If you run this script:
131
132 .. code-block:: text
133
134 $ casperjs c.js --foo=01234567
135 1234567
136
137 As you can see, the ``01234567`` value has been cast to a *Number*.
138
139 Sometimes, you just want the original string; then you can use the ``raw`` property of the ``cli`` object, which contains the raw values passed parameters::
140
141 var casper = require('casper').create();
142 var utils = require('utils');
143
144 utils.dump(casper.cli.get('foo'));
145 utils.dump(casper.cli.raw.get('foo'));
146
147 casper.exit();
148
149 Sample usage:
150
151 .. code-block:: text
152
153 $ casperjs c.js --foo=01234567
154 1234567
155 "01234567"
156
1 # -*- coding: utf-8 -*-
2 #
3 # CasperJS documentation
4 #
5 # If extensions (or modules to document with autodoc) are in another directory,
6 # add these directories to sys.path here. If the directory is relative to the
7 # documentation root, use os.path.abspath to make it absolute, like shown here.
8 #sys.path.insert(0, os.path.abspath('.'))
9
10 from datetime import date
11
12 # -- General configuration -----------------------------------------------------
13
14 # If your documentation needs a minimal Sphinx version, state it here.
15 #needs_sphinx = '1.0'
16
17 # Add any Sphinx extension module names here, as strings. They can be extensions
18 # coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
19 extensions = ['sphinx.ext.autodoc', 'sphinx.ext.extlinks']
20
21 # Add any paths that contain templates here, relative to this directory.
22 templates_path = ['_templates']
23
24 highlight_language = 'javascript'
25
26 # The suffix of source filenames.
27 source_suffix = '.rst'
28
29 # Prolog
30 rst_prolog = ('.. note:: This is the documentation for the |release| version of'
31 ' CasperJS. Find docs for 1.0 stable'
32 ' `on the official website <http://casperjs.org/>`_.\n')
33
34 # The encoding of source files.
35 source_encoding = 'utf-8'
36
37 # The master toctree document.
38 master_doc = 'index'
39
40 # General information about the project.
41 project = u'CasperJS'
42 copyright = (u'2011-%d Nicolas Perriault and contributors. CasperJS logo by Jeremy Forveille'
43 % date.today().year)
44
45 # The version info for the project you're documenting, acts as replacement for
46 # |version| and |release|, also used in various other places throughout the
47 # built documents.
48 #
49 # The short X.Y version.
50 version = '1.1'
51 # The full version, including alpha/beta/rc tags.
52 release = '1.1.0-DEV'
53
54 # The language for content autogenerated by Sphinx. Refer to documentation
55 # for a list of supported languages.
56 #language = None
57
58 # There are two options for replacing |today|: either, you set today to some
59 # non-false value, then it is used:
60 #today = ''
61 # Else, today_fmt is used as the format for a strftime call.
62 #today_fmt = '%B %d, %Y'
63
64 # List of patterns, relative to source directory, that match files and
65 # directories to ignore when looking for source files.
66 exclude_patterns = ['_build', 'README.md']
67
68 # The reST default role (used for this markup: `text`) to use for all documents.
69 #default_role = None
70
71 # If true, '()' will be appended to :func: etc. cross-reference text.
72 #add_function_parentheses = True
73
74 # If true, the current module name will be prepended to all description
75 # unit titles (such as .. function::).
76 #add_module_names = True
77
78 # If true, sectionauthor and moduleauthor directives will be shown in the
79 # output. They are ignored by default.
80 #show_authors = False
81
82 # The name of the Pygments (syntax highlighting) style to use.
83 #pygments_style = 'default'
84
85 # A list of ignored prefixes for module index sorting.
86 #modindex_common_prefix = []
87
88
89 # -- Options for HTML output ---------------------------------------------------
90
91 # The theme to use for HTML and HTML Help pages. See the documentation for
92 # a list of builtin themes.
93 html_theme = 'casperjs'
94
95 # Theme options are theme-specific and customize the look and feel of a theme
96 # further. For a list of options available for each theme, see the
97 # documentation.
98 #html_theme_options = {}
99
100 # Add any paths that contain custom themes here, relative to this directory.
101 html_theme_path = ['_themes']
102
103 # The name for this set of Sphinx documents. If None, it defaults to
104 # "<project> v<release> documentation".
105 #html_title = None
106
107 # A shorter title for the navigation bar. Default is the same as html_title.
108 #html_short_title = None
109
110 # The name of an image file (relative to this directory) to place at the top
111 # of the sidebar.
112 #html_logo = None
113
114 # The name of an image file (within the static path) to use as favicon of the
115 # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
116 # pixels large.
117 html_favicon = 'casperjs-favicon.ico'
118
119 # Add any paths that contain custom static files (such as style sheets) here,
120 # relative to this directory. They are copied after the builtin static files,
121 # so a file named "default.css" will overwrite the builtin "default.css".
122 html_static_path = ['_static']
123
124 # If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
125 # using the given strftime format.
126 #html_last_updated_fmt = '%b %d, %Y'
127
128 # If true, SmartyPants will be used to convert quotes and dashes to
129 # typographically correct entities.
130 #html_use_smartypants = True
131
132 # Custom sidebar templates, maps document names to template names.
133 html_sidebars = {
134 '*': [
135 'globaltoc.html',
136 'relations.html',
137 'sourcelink.html',
138 'searchbox.html',
139 'addon.html'
140 ],
141 'modules/*': [
142 'localtoc.html',
143 'globaltoc.html',
144 'relations.html',
145 'sourcelink.html',
146 'searchbox.html',
147 'addon.html'
148 ],
149 }
150
151 # Additional templates that should be rendered to pages, maps page names to
152 # template names.
153 #html_additional_pages = {}
154
155 # If false, no module index is generated.
156 #html_domain_indices = True
157
158 # If false, no index is generated.
159 #html_use_index = True
160
161 # If true, the index is split into individual pages for each letter.
162 #html_split_index = False
163
164 # If true, links to the reST sources are added to the pages.
165 #html_show_sourcelink = True
166
167 # If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
168 #html_show_sphinx = True
169
170 # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
171 #html_show_copyright = True
172
173 # If true, an OpenSearch description file will be output, and all pages will
174 # contain a <link> tag referring to it. The value of this option must be the
175 # base URL from which the finished HTML is served.
176 #html_use_opensearch = ''
177
178 # This is the file name suffix for HTML files (e.g. ".xhtml").
179 #html_file_suffix = None
180
181 # Output file base name for HTML help builder.
182 htmlhelp_basename = 'casper-docs'
183
184
185 # -- Options for LaTeX output --------------------------------------------------
186
187 latex_elements = {
188 # The paper size ('letterpaper' or 'a4paper').
189 #'papersize': 'letterpaper',
190
191 # The font size ('10pt', '11pt' or '12pt').
192 #'pointsize': '10pt',
193
194 # Additional stuff for the LaTeX preamble.
195 #'preamble': '',
196 }
197
198 # Grouping the document tree into LaTeX files. List of tuples
199 # (source start file, target name, title, author, documentclass [howto/manual]).
200 # latex_documents = [
201 # (),
202 # ]
203
204 # The name of an image file (relative to this directory) to place at the top of
205 # the title page.
206 #latex_logo = None
207
208 # For "manual" documents, if this is true, then toplevel headings are parts,
209 # not chapters.
210 #latex_use_parts = False
211
212 # If true, show page references after internal links.
213 #latex_show_pagerefs = False
214
215 # If true, show URL addresses after external links.
216 #latex_show_urls = False
217
218 # Documents to append as an appendix to all manuals.
219 #latex_appendices = []
220
221 # If false, no module index is generated.
222 #latex_domain_indices = True
223
224
225 # -- Options for manual page output --------------------------------------------
226
227 # One entry per manual page. List of tuples
228 # (source start file, name, description, authors, manual section).
229 man_pages = [
230 ('index', 'casperjs', u'casperjs documentation', [u'Nicolas Perriault'], 1)
231 ]
232
233 # If true, show URL addresses after external links.
234 #man_show_urls = False
235
236
237 # -- Options for Texinfo output ------------------------------------------------
238
239 # Grouping the document tree into Texinfo files. List of tuples
240 # (source start file, target name, title, author,
241 # dir menu entry, description, category)
242 texinfo_documents = [
243 ('index', 'CasperJS', u'CasperJS Documentation',
244 u'Nicolas Perriault', 'CasperJS', 'CasperJS docs.', 'Miscellaneous'),
245 ]
246
247 # Documents to append as an appendix to all manuals.
248 #texinfo_appendices = []
249
250 # If false, no module index is generated.
251 #texinfo_domain_indices = True
252
253 # How to display URL addresses: 'footnote', 'no', or 'inline'.
254 #texinfo_show_urls = 'footnote'
255
256
257 extlinks = {
258 'issue': ('https://github.com/n1k0/casperjs/issues/%s', '#'),
259 'repo': ('https://github.com/n1k0/casperjs/%s', ''),
260 }
1 Credits
2 =======
3
4 Author
5 ------
6
7 CasperJS is mainly developed by `Nicolas Perriault <https://nicolas.perriault.net/>`_ 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 <http://www.forveillejeremy.com/>`_
1 .. _debugging:
2
3 .. index:: Bugs, Debugging
4
5 =========
6 Debugging
7 =========
8
9 .. contents:: A few tips for debugging your casper scripts:
10 :local:
11
12
13 Use the :index:`verbose` mode
14 -----------------------------
15
16 By default & by design, a ``Casper`` instance won't print anything to the console. This can be very limitating & frustrating when creating or debugging scripts, so a good practice is to always start coding a script using these :index:`settings`::
17
18 var casper = require('casper').create({
19 verbose: true,
20 logLevel: "debug"
21 });
22
23 The ``verbose`` setting will tell Casper to write every logged message at the ``logLevel`` logging level onto the standard output, so you'll be able to trace every step made.
24
25 .. warning::
26
27 Output will then be pretty verbose, and will potentially display sensitive informations onto the console. **Use with care on production.**
28
29
30 Hook in the deep using :index:`events`
31 --------------------------------------
32
33 :doc:`Events <events-filters>` are a very powerful features of CasperJS, and you should probably give it a look if you haven't already.
34
35 Some interesting events you may eventually use to debug your scripts:
36
37 - The ``http.status.XXX`` event will be emitted everytime a resource is sent with the `HTTP code <http://en.wikipedia.org/wiki/List_of_HTTP_status_codes>`_ corresponding to ``XXX``;
38 - The ``remote.alert`` everytime an ``alert()`` call is performed client-side;
39 - ``remote.message`` everytime a message is sent to the client-side console;
40 - ``step.added`` everytime a step is added to the stack;
41 - etc…
42
43 Listening to an event is dead easy::
44
45 casper.on('http.status.404', function(resource) {
46 this.log('Hey, this one is 404: ' + resource.url, 'warning');
47 });
48
49 Ensure to check the :ref:`full list <events_list>` of all the other available events.
50
51
52 .. _debugging_dump:
53
54 Dump serialized values to the console
55 -------------------------------------
56
57 Sometimes it's helpful to inspect a variable, especially Object contents. The :ref:`utils_dump() <utils_dump>` function can achieve just that::
58
59 require('utils').dump({
60 foo: {
61 bar: 42
62 },
63 });
64
65 .. note::
66
67 :ref:`utils_dump() <utils_dump>` won't be able to serialize function nor complex cyclic structures though.
68
69
70 Localize yourself in modules
71 ----------------------------
72
73 If you're creating Casper modules, a cool thing to know is that there's a special built-in variable available in every module, ``__file__``, which contains the absolute path to current javascript file (the module file).
74
75
76 Name your closures
77 ------------------
78
79 Probably one of the most easy but effective best practice, always name your closures:
80
81 **Hard to track:**
82
83 ::
84
85 casper.start('http://foo.bar/', function() {
86 this.evaluate(function() {
87 // ...
88 });
89 });
90
91 **Easier:**
92
93 ::
94
95 casper.start('http://foo.bar/', function afterStart() {
96 this.evaluate(function evaluateStuffAfterStart() {
97 // ...
98 });
99 });
100
101 That way, everytime one is failing, its name will be printed out in the :index:`stack trace`, **so you can more easily locate it within your code**.
102
103 .. note::
104
105 This one also applies for all your other Javascript works, of course ;)
1 .. _extending:
2
3 .. index:: extending, inheritance, prototype
4
5 =========
6 Extending
7 =========
8
9 Sometimes it can be convenient to add your own methods to a ``Casper`` object instance; you can easily do so as illustrated in the example below::
10
11 var casper = require('casper').create({
12 verbose: true,
13 logLevel: "debug"
14 });
15
16 var links = {
17 'http://edition.cnn.com/': 0,
18 'http://www.nytimes.com/': 0,
19 'http://www.bbc.co.uk/': 0,
20 'http://www.guardian.co.uk/': 0
21 };
22
23 casper.countLinks = function() {
24 return this.evaluate(function() {
25 return __utils__.findAll('a[href]').length;
26 });
27 };
28
29 casper.renderJSON = function(what) {
30 return this.echo(JSON.stringify(what, null, ' '));
31 };
32
33 casper.start();
34
35 casper.each(Object.keys(links), function(casper, link) {
36 this.thenOpen(link, function() {
37 links[link] = this.countLinks();
38 });
39 });
40
41 casper.run(function() {
42 this.renderJSON(links).exit();
43 });
44
45 But that's just plain old *monkey-patching* the ``casper`` object, and you may probably want a more OO approach… That's where the ``inherits()`` function from the ``utils`` module and ported from `nodejs <http://nodejs.org/>`_ comes handy::
46
47 var Casper = require('casper').Casper;
48 var utils = require('utils');
49 var links = {
50 'http://edition.cnn.com/': 0,
51 'http://www.nytimes.com/': 0,
52 'http://www.bbc.co.uk/': 0,
53 'http://www.guardian.co.uk/': 0
54 };
55
56 function Fantomas() {
57 Fantomas.super_.apply(this, arguments);
58 }
59
60 // Let's make our Fantomas class extending the Casper one
61 // please note that at this point, CHILD CLASS PROTOTYPE WILL BE OVERRIDEN
62 utils.inherits(Fantomas, Casper);
63
64 Fantomas.prototype.countLinks = function() {
65 return this.evaluate(function() {
66 return __utils__.findAll('a[href]').length;
67 });
68 };
69
70 Fantomas.prototype.renderJSON = function(what) {
71 return this.echo(JSON.stringify(what, null, ' '));
72 };
73
74 var fantomas = new Fantomas({
75 verbose: true,
76 logLevel: "debug"
77 });
78
79 fantomas.start();
80
81 Object.keys(links).forEach(function(url) {
82 fantomas.thenOpen(url, function() {
83 links[url] = this.countLinks();
84 });
85 });
86
87 fantomas.run(function() {
88 this.renderJSON(links).exit();
89 });
90
91 .. note::
92
93 The use of the ``super_`` child class property which becomes available once its parent has been defined using ``inherits()``; it contains a reference to the parent constructor.
94
95 **Don't forget to call ``Casper``'s parent constructor!**
96
97 Of course this approach is bit more verbose than the easy *monkey-patching* one, so please ensure you're not just overengineering stuff by subclassing the ``Casper`` class.
98
99
100 .. index:: coffeescript
101
102 Using CoffeeScript
103 ~~~~~~~~~~~~~~~~~~
104
105 If you're writing your casper scripts using `CoffeeScript <http://coffeescript.org/>`_, extending casper is getting a bit more straightforward:
106
107 .. code-block:: coffeescript
108
109 links =
110 'http://edition.cnn.com/': 0
111 'http://www.nytimes.com/': 0
112 'http://www.bbc.co.uk/': 0
113 'http://www.guardian.co.uk/': 0
114
115 class Fantomas extends require('casper').Casper
116 countLinks: ->
117 @evaluate ->
118 __utils__.findAll('a').length
119
120 renderJSON: (what) ->
121 @echo JSON.stringify what, null, ' '
122
123 fantomas = new Fantomas
124 loadImages: false
125 logLevel: "debug"
126 verbose: true
127
128 fantomas.start()
129
130 for url of links
131 do (url) ->
132 fantomas.thenOpen url, ->
133 links[url] = @countLinks()
134
135 fantomas.run ->
136 @renderJSON links
137 @exit()
138
This diff is collapsed. Click to expand it.
1 ======================
2 CasperJS documentation
3 ======================
4
5 CasperJS_ is a navigation scripting & testing utility for PhantomJS_, 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 changelog
26 upgrading/index
27 credits
28 license
29
30 You can also search the :ref:`genindex` if you're looking for something particular.
31
32 .. index:: Community, Contributing, Help, Support
33
34 Community
35 ---------
36
37 - `get the code <https://github.com/n1k0/casperjs>`_ and `contribute <https://github.com/n1k0/casperjs/blob/master/CONTRIBUTING.md#contribution-guide>`_
38 - join the `mailing list <https://groups.google.com/forum/#!forum/casperjs>`_
39 - check out `the ecosystem <https://github.com/casperjs>`_
40 - follow `@casperjs\_org <https://twitter.com/casperjs_org>`_ on Twitter
41 - there's also a `Google+ account <https://plus.google.com/106641872690063476159>`_ (not much updated though)
42
43
44 .. _CasperJS: http://casperjs.org/
45 .. _PhantomJS: http://phantomjs.org/
1 .. _installation:
2 .. index:: Installation
3
4 ============
5 Installation
6 ============
7
8 CasperJS can be installed on most Linuxes, OSX and Windows.
9
10 Prerequisites
11 -------------
12
13 .. index:: PhantomJS, Python
14
15 - PhantomJS_ 1.8.1 or greater. Installation instructions can be found `here <http://phantomjs.org/download.html>`_
16 - Python_ 2.6 or greater
17
18 .. note::
19
20 .. versionadded:: 1.0
21
22 A `Ruby <http://ruby-lang.org/>`_ version of the ``casperjs`` executable is also available in the ``rubybin/`` directory; in order to use the :index:`Ruby` version instead of the Python one:
23
24 .. code-block:: text
25
26 $ ln -sf `pwd`/rubybin/casperjs /usr/local/bin/casperjs
27
28 Or using the ruby interpreter:
29
30 .. code-block:: text
31
32 $ ruby /path/to/casperjs/rubybin/casperjs
33 CasperJS version 1.1-DEV at /path/to/casperjs/rubybin/casperjs, using PhantomJS version 1.7.0
34 ...
35
36 .. index:: Homebrew
37
38 Installing from Homebrew (OSX)
39 ------------------------------
40
41 Installation of both PhantomJS and CasperJS can be achieved through `Homebrew <http://mxcl.github.com/homebrew/>`_::
42
43 $ brew install casperjs
44
45 .. index:: git
46
47 Installing from git
48 -------------------
49
50 Installation can be achieved using `git <http://git-scm.com/>`_. The code is mainly hosted on `Github <https://github.com/n1k0/casperjs>`_.
51
52 From a stable tag
53 ~~~~~~~~~~~~~~~~~
54
55 .. code-block:: text
56
57 $ git clone git://github.com/n1k0/casperjs.git
58 $ cd casperjs
59 $ git checkout tags/1.0
60 $ ln -sf `pwd`/bin/casperjs /usr/local/bin/casperjs
61
62 Once PhantomJS and CasperJS installed on your machine, you should obtain something like this:
63
64 .. code-block:: text
65
66 $ phantomjs --version
67 1.7
68 $ casperjs --version
69 1.0
70
71 From the master branch
72 ~~~~~~~~~~~~~~~~~~~~~~
73
74 The ``master`` branch hosts the current development version of CasperJS.
75
76 .. code-block:: text
77
78 $ git clone git://github.com/n1k0/casperjs.git
79 $ cd casperjs
80 $ git checkout master
81 $ ln -sf `pwd`/bin/casperjs /usr/local/bin/casperjs
82
83 To check your current installed version:
84
85 .. code-block:: text
86
87 $ casperjs --version
88 1.1-DEV
89
90 You are now ready to write your :doc:`first script <quickstart>`!
91
92
93 Installing from an archive
94 --------------------------
95
96 You can download tagged archives of CasperJS code:
97
98 **Latest stable version:**
99
100 - https://github.com/n1k0/casperjs/zipball/1.0.0 (zip)
101 - https://github.com/n1k0/casperjs/tarball/1.0.0 (tar.gz)
102
103 **Latest development version (master branch):**
104
105 - https://github.com/n1k0/casperjs/zipball/master (zip)
106 - https://github.com/n1k0/casperjs/tarball/master (tar.gz)
107
108 Operations are then the same as with a git checkout.
109
110
111 .. index:: Windows
112
113 CasperJS on Windows
114 -------------------
115
116 Phantomjs installation additions
117 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
118
119 - Append ``";C:\phantomjs"`` to your ``PATH`` environment variable.
120 - Modify this path appropriately if you installed PhantomJS to a different location.
121
122 Casperjs installation additions
123 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
124
125 .. versionadded:: 1.0
126
127 CasperJS, as of 1.0.0-RC3, ships with a Batch script so you don't need Python nor Ruby to use it.
128
129 - Append ``";C:\casperjs\batchbin"`` to your ``PATH`` environment variable.
130 - Modify this path appropriately if you installed CasperJS to a different location.
131
132 You can now run any regular casper scripts that way:
133
134 .. code-block:: text
135
136 C:> casperjs.bat myscript.js
137
138 Earlier versions of CasperJS
139 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
140
141 Before 1.0.0-RC3, you had to setup your casper scripts that way::
142
143 phantom.casperPath = 'C:\\casperjs-1.1';
144 phantom.injectJs(phantom.casperPath + '\\bin\\bootstrap.js');
145
146 var casper = require('casper').create();
147
148 // do stuff
149
150 Run the script using the ``phantom.exe`` program:
151
152 .. code-block:: text
153
154 C:> phantomjs.exe myscript.js
155
156 .. note::
157
158 There is no output coloration when running CasperJS on Microsoft platforms.
159
160
161 .. index:: Bugs, REPL
162
163 Known Bugs & Limitations
164 ------------------------
165
166 - Due to its asynchronous nature, CasperJS doesn't work well with `PhantomJS' REPL <http://code.google.com/p/phantomjs/wiki/InteractiveModeREPL>`_.
167
168 .. _PhantomJS: http://phantomjs.org/
169 .. _Python: http://python.org/
1 .. _license:
2
3 .. index:: Licensing
4
5 =======
6 License
7 =======
8
9 `CasperJS <http://casperjs.org>`_ is released under the terms of the
10 `MIT license <http://en.wikipedia.org/wiki/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.
1 .. _logging:
2
3 .. index:: Logging, log levels
4
5 =======
6 Logging
7 =======
8
9 CasperJS allows logging using the :ref:`casper.log() <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.
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() <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 <colorizer_styles>`.
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
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 <https://github.com/n1k0/casperjs/issues/new>`_.
10
11 .. toctree::
12 :glob:
13
14 *
1 .. _utils_module:
2
3 .. index:: Utilities, Helpers
4
5 ====================
6 The ``utils`` module
7 ====================
8
9 This module provides simple helper functions, some of them being very specific to CasperJS though.
10
11 Functions reference
12 +++++++++++++++++++
13
14 Usage is pretty much straightforward::
15
16 var utils = require('utils');
17
18 utils.dump({plop: 42});
19
20 ``betterTypeOf()``
21 -------------------------------------------------------------------------------
22
23 **Signature:** ``betterTypeOf(input)``
24
25 Provides a better ``typeof`` operator equivalent, eg. able to retrieve the ``Array`` type.
26
27 .. index:: dump, Serialization, Debugging, JSON
28
29 .. _utils_dump:
30
31 ``dump()``
32 -------------------------------------------------------------------------------
33
34 **Signature:** ``dump(value)``
35
36 Dumps a JSON_ representation of passed argument to the standard output. Useful for :ref:`debugging your scripts <debugging_dump>`.
37
38 ``fileExt()``
39 -------------------------------------------------------------------------------
40
41 **Signature:** ``fileExt(file)``
42
43 Retrieves the extension of passed filename.
44
45 ``fillBlanks()``
46 -------------------------------------------------------------------------------
47
48 **Signature:** ``fillBlanks(text, pad)``
49
50 Fills a string with trailing spaces to match ``pad`` length.
51
52 .. index:: String formatting
53
54 ``format()``
55 -------------------------------------------------------------------------------
56
57 **Signature:** ``format(f)``
58
59 Formats a string against passed args. ``sprintf`` equivalent.
60
61 .. note::
62
63 This is a port of nodejs ``util.format()``.
64
65 ``getPropertyPath()``
66 -------------------------------------------------------------------------------
67
68 **Signature:** ``getPropertyPath(Object obj, String path)``
69
70 .. versionadded:: 1.0
71
72 Retrieves the value of an Object foreign property using a dot-separated path string::
73
74 var account = {
75 username: 'chuck',
76 skills: {
77 kick: {
78 roundhouse: true
79 }
80 }
81 }
82 utils.getPropertyPath(account, 'skills.kick.roundhouse'); // true
83
84 .. warning::
85
86 This function doesn't handle object key names containing a dot.
87
88 .. index:: inheritance
89
90 ``inherits()``
91 -------------------------------------------------------------------------------
92
93 **Signature:** ``inherits(ctor, superCtor)``
94
95 Makes a constructor inheriting from another. Useful for subclassing and :doc:`extending <../extending>`.
96
97 .. note::
98
99 This is a port of nodejs ``util.inherits()``.
100
101 ``isArray()``
102 -------------------------------------------------------------------------------
103
104 **Signature:** ``isArray(value)``
105
106 Checks if passed argument is an instance of ``Array``.
107
108 ``isCasperObject()``
109 -------------------------------------------------------------------------------
110
111 **Signature:** ``isCasperObject(value)``
112
113 Checks if passed argument is an instance of ``Casper``.
114
115 ``isClipRect()``
116 -------------------------------------------------------------------------------
117
118 **Signature:** ``isClipRect(value)``
119
120 Checks if passed argument is a ``cliprect`` object.
121
122 .. index:: falsiness
123
124 ``isFalsy()``
125 -------------------------------------------------------------------------------
126
127 **Signature:** ``isFalsy(subject)``
128
129 .. versionadded:: 1.0
130
131 Returns subject `falsiness <http://11heavens.com/falsy-and-truthy-in-javascript>`_.
132
133 ``isFunction()``
134 -------------------------------------------------------------------------------
135
136 **Signature:** ``isFunction(value)``
137
138 Checks if passed argument is a function.
139
140 ``isJsFile()``
141 -------------------------------------------------------------------------------
142
143 **Signature:** ``isJsFile(file)``
144
145 Checks if passed filename is a Javascript one (by checking if it has a ``.js`` or ``.coffee`` file extension).
146
147 ``isNull()``
148 -------------------------------------------------------------------------------
149
150 **Signature:** ``isNull(value)``
151
152 Checks if passed argument is a ``null``.
153
154 ``isNumber()``
155 -------------------------------------------------------------------------------
156
157 **Signature:** ``isNumber(value)``
158
159 Checks if passed argument is an instance of ``Number``.
160
161 ``isObject()``
162 -------------------------------------------------------------------------------
163
164 **Signature:** ``isObject(value)``
165
166 Checks if passed argument is an object.
167
168 ``isString()``
169 -------------------------------------------------------------------------------
170
171 **Signature:** ``isString(value)``
172
173 Checks if passed argument is an instance of ``String``.
174
175 .. index:: truthiness
176
177 ``isTruthy()``
178 -------------------------------------------------------------------------------
179
180 **Signature:** ``isTruthy(subject)``
181
182 .. versionadded:: 1.0
183
184 Returns subject `truthiness <http://11heavens.com/falsy-and-truthy-in-javascript>`_.
185
186 ``isType()``
187 -------------------------------------------------------------------------------
188
189 **Signature:** ``isType(what, type)``
190
191 Checks if passed argument has its type matching the ``type`` argument.
192
193 ``isUndefined()``
194 -------------------------------------------------------------------------------
195
196 **Signature:** ``isUndefined(value)``
197
198 Checks if passed argument is ``undefined``.
199
200 ``isWebPage()``
201 -------------------------------------------------------------------------------
202
203 **Signature:** ``isWebPage(what)``
204
205 Checks if passed argument is an instance of native PhantomJS' ``WebPage`` object.
206
207 ``mergeObjects()``
208 -------------------------------------------------------------------------------
209
210 **Signature:** ``mergeObjects(origin, add)``
211
212 Merges two objects recursively.
213
214 .. index:: DOM
215
216 ``node()``
217 -------------------------------------------------------------------------------
218
219 **Signature:** ``node(name, attributes)``
220
221 Creates an (HT\|X)ML element, having optional ``attributes`` added.
222
223 .. index:: JSON
224
225 ``serialize()``
226 -------------------------------------------------------------------------------
227
228 **Signature:** ``serialize(value)``
229
230 Serializes a value using JSON_ format. Will serialize functions as strings. Useful for :doc:`debugging <../debugging>` and comparing objects.
231
232 ``unique()``
233 -------------------------------------------------------------------------------
234
235 **Signature:** ``unique(array)``
236
237 Retrieves unique values from within a given ``Array``.
238
239 .. _JSON: http://json.org/
1 .. _quickstart:
2
3 ==========
4 Quickstart
5 ==========
6
7 Once CasperJS is :doc:`properly installed <installation>`, you can write your first script. You can use plain :ref:`Javascript <quickstart_javascript>` or :ref:`CoffeeScript <quickstart_coffeescript>`.
8
9 .. hint::
10
11 If you're not too comfortable with Javascript, a :ref:`dedicated FAQ entry <faq_javascript>` is waiting for you.
12
13 .. _quickstart_javascript:
14
15 A minimal scraping script
16 -------------------------
17
18 Fire up your favorite editor, create and save a ``sample.js`` file like below::
19
20 var casper = require('casper').create();
21
22 casper.start('http://casperjs.org/', function() {
23 this.echo(this.getTitle());
24 });
25
26 casper.thenOpen('http://phantomjs.org', function() {
27 this.echo(this.getTitle());
28 });
29
30 casper.run();
31
32 Run it:
33
34 .. code-block:: text
35
36 $ casperjs sample.js
37
38 You should get something like this:
39
40 .. code-block:: text
41
42 $ casperjs c.js
43 CasperJS, a navigation scripting and testing utility for PhantomJS | CasperJS 1.0.0
44 PhantomJS: Headless WebKit with JavaScript API
45
46 .. topic:: What did we just do?
47
48 1. we created a new :ref:`Casper <casper_module>` instance
49 2. we started it and opened ``http://casperjs.org/``
50 3. *once* the page has been loaded, we asked to print the title of that webpage (the content of its ``<title>`` tag)
51 4. *then* we opened another url, ``http://phantomjs.org/``
52 5. *once* the new page has been loaded, we asked to print its title too
53 6. we executed the whole process
54
55
56 Now let's scrape Google!
57 ------------------------
58
59 In the following example, we'll query google for two terms consecutively, *"casperjs"* and *"phantomjs"*, aggregate the result links in a standard ``Array`` and output the result to the console.
60
61 Fire up your favorite editor and save the javascript code below in a
62 ``googlelinks.js`` file::
63
64 var links = [];
65 var casper = require('casper').create();
66
67 function getLinks() {
68 var links = document.querySelectorAll('h3.r a');
69 return Array.prototype.map.call(links, function(e) {
70 return e.getAttribute('href')
71 });
72 }
73
74 casper.start('http://google.fr/', function() {
75 // search for 'casperjs' from google form
76 this.fill('form[action="/search"]', { q: 'casperjs' }, true);
77 });
78
79 casper.then(function() {
80 // aggregate results for the 'casperjs' search
81 links = this.evaluate(getLinks);
82 // now search for 'phantomjs' by filling the form again
83 this.fill('form[action="/search"]', { q: 'phantomjs' }, true);
84 });
85
86 casper.then(function() {
87 // aggregate results for the 'phantomjs' search
88 links = links.concat(this.evaluate(getLinks));
89 });
90
91 casper.run(function() {
92 // echo results in some pretty fashion
93 this.echo(links.length + ' links found:');
94 this.echo(' - ' + links.join('\n - ')).exit();
95 });
96
97 Run it:
98
99 .. code-block:: text
100
101 $ casperjs googlelinks.js
102 20 links found:
103 - https://github.com/n1k0/casperjs
104 - https://github.com/n1k0/casperjs/issues/2
105 - https://github.com/n1k0/casperjs/tree/master/samples
106 - https://github.com/n1k0/casperjs/commits/master/
107 - http://www.facebook.com/people/Casper-Js/100000337260665
108 - http://www.facebook.com/public/Casper-Js
109 - http://hashtags.org/tag/CasperJS/
110 - http://www.zerotohundred.com/newforums/members/casper-js.html
111 - http://www.yellowpages.com/casper-wy/j-s-enterprises
112 - http://local.trib.com/casper+wy/j+s+chinese+restaurant.zq.html
113 - http://www.phantomjs.org/
114 - http://code.google.com/p/phantomjs/
115 - http://code.google.com/p/phantomjs/wiki/QuickStart
116 - http://svay.com/blog/index/post/2011/08/31/Paris-JS-10-%3A-Introduction-%C3%A0-PhantomJS
117 - https://github.com/ariya/phantomjs
118 - http://dailyjs.com/2011/01/28/phantoms/
119 - http://css.dzone.com/articles/phantom-js-alternative
120 - http://pilvee.com/blog/tag/phantom-js/
121 - http://ariya.blogspot.com/2011/01/phantomjs-minimalistic-headless-webkit.html
122 - http://www.readwriteweb.com/hack/2011/03/phantomjs-the-power-of-webkit.php
123
124
125 .. _quickstart_coffeescript:
126
127 .. index:: coffeescript
128
129 CoffeeScript version
130 --------------------
131
132 You can also write Casper scripts using the `CoffeeScript syntax <http://jashkenas.github.com/coffee-script/>`_:
133
134 .. code-block:: coffeescript
135
136 getLinks = ->
137 links = document.querySelectorAll "h3.r a"
138 Array::map.call links, (e) -> e.getAttribute "href"
139
140 links = []
141 casper = require('casper').create()
142
143 casper.start "http://google.fr/", ->
144 # search for 'casperjs' from google form
145 @fill "form[action='/search']", q: "casperjs", true
146
147 casper.then ->
148 # aggregate results for the 'casperjs' search
149 links = @evaluate getLinks
150 # search for 'phantomjs' from google form
151 @fill "form[action='/search']", q: "phantomjs", true
152
153 casper.then ->
154 # concat results for the 'phantomjs' search
155 links = links.concat @evaluate(getLinks)
156
157 casper.run ->
158 # display results
159 @echo links.length + " links found:"
160 @echo(" - " + links.join("\n - ")).exit()
161
162 Just remember to suffix your script with the ``.coffee`` extension.
163
164 A minimal testing script
165 ------------------------
166
167 CasperJS is also a :ref:`testing framework <testing>`; test scripts are slightly different than scraping ones, though they share most of their API. A simplest test script::
168
169 // hello-test.js
170 casper.test.assert(true);
171 casper.test.done();
172
173 Run it using the ``casperjs test`` subcommand:
174
175 .. code-block:: text
176
177 $ casperjs test hello-test.js
178 Test file: hello-test.js
179 PASS Subject is strictly true
180 PASS 1 tests executed in 0.103s, 1 passed, 0 failed.
181
182 .. note::
183
184 As you can see, there's no need to create a ``casper`` instance in a test script as a preconfigured one has already made available for you.
185
186 You can read more about testing in the :ref:`dedicated section <testing>`.
1 .. _selectors:
2
3 .. index:: selector, DOM, HTML
4
5 =========
6 Selectors
7 =========
8
9 CasperJS makes an heavy use of selectors in order to work with the `DOM <http://www.w3.org/TR/dom/>`_, and can transparently use either `CSS3 <http://www.w3.org/TR/selectors/>`_ or `XPath <http://www.w3.org/TR/xpath/>`_ expressions.
10
11 All the examples below are based on this HTML code:
12
13 .. code-block:: html
14
15 <!doctype html>
16 <html>
17 <head>
18 <meta charset="utf-8">
19 <title>My page</title>
20 </head>
21 <body>
22 <h1 class="page-title">Hello</h1>
23 <ul>
24 <li>one</li>
25 <li>two</li>
26 <li>three</li>
27 </ul>
28 <footer><p>©2012 myself</p></footer>
29 </body>
30 </html>
31
32 .. index:: CSS, CSS3
33
34 CSS3
35 ----
36
37 By default, CasperJS accepts `CSS3 selector strings <http://www.w3.org/TR/selectors/#selectors>`_ to check for elements within the DOM.
38
39 To check if the ``<h1 class="page-title">`` 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 <testing>`::
52
53 casper.test.begin('The heading exists', 1, function suite(test) {
54 casper.start('http://domain.tld/page.html', function() {
55 this.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 this.assertExists('h1.page-title');
66 this.assertSelectorHasText('h1.page-title', 'Hello');
67 this.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 <http://en.wikipedia.org/wiki/XPath>`_ 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() <casper_fill>` method when you want to fill **file fields**; PhantomJS natively only allows the use of CSS3 selectors in its `uploadFile method <https://github.com/ariya/phantomjs/wiki/API-Reference#wiki-webpage-uploadFile>`_, hence this limitation.
1 .. _testing:
2
3 .. index:: Testing
4
5 =======
6 Testing
7 =======
8
9 CasperJS ships with its own :doc:`testing framework <modules/tester>`, providing a handful set of tools to ease testing your webapps.
10
11 .. warning::
12
13 .. versionchanged:: 1.1
14
15 The testing framework — hence its whole API — can only be used when using the ``casperjs test`` subcommand.
16
17 If you try to use the ``casper.test`` property out of the testing environment, you'll get an error.
18
19 .. index:: Unit testing
20
21 Unit testing
22 ------------
23
24 Imagine a dumb ``Cow`` object we want to unit test::
25
26 function Cow() {
27 this.mowed = false;
28 this.moo = function moo() {
29 this.mowed = true; // mootable state: don't do that at home
30 return 'moo!';
31 };
32 }
33
34 Let's write a tiny test suite for it::
35
36 // cow-test.js
37 casper.test.begin('Cow can moo', 2, function suite(test) {
38 var cow = new Cow();
39 test.assertEquals(cow.moo(), 'moo!');
40 test.assert(cow.mowed);
41 test.done();
42 });
43
44 Run the tests using the ``casperjs test`` command:
45
46 .. code-block:: text
47
48 $ casperjs test cow-test.js
49
50 You should theoretically get something like this:
51
52 .. figure:: _static/images/cow-test-ok.png
53 :align: center
54
55 Make it fail::
56
57 casper.test.begin('Cow can moo', 2, function suite(test) {
58 var cow = new Cow();
59 test.assertEquals(cow.moo(), 'BAZINGA!');
60 test.assert(cow.mowed);
61 test.done();
62 });
63
64 You'll get this instead:
65
66 .. figure:: _static/images/cow-test-ko.png
67 :align: center
68
69 .. hint::
70
71 The whole ``tester`` module API is documented :doc:`here <modules/tester>`.
72
73
74 .. index:: Functional testing, Browser testing, Test suite
75
76 Browser tests
77 -------------
78
79 Now let's write a suite for testing google search (yes, you read it well)::
80
81 // googletesting.js
82 casper.test.begin('Google search retrieves 10 or more results', 5, function suite(test) {
83 casper.start("http://www.google.fr/", function() {
84 test.assertTitle("Google", "google homepage title is the one expected");
85 test.assertExists('form[action="/search"]', "main form is found");
86 this.fill('form[action="/search"]', {
87 q: "casperjs"
88 }, true);
89 });
90
91 casper.then(function() {
92 test.assertTitle("casperjs - Recherche Google", "google title is ok");
93 test.assertUrlMatch(/q=casperjs/, "search term has been submitted");
94 test.assertEval(function() {
95 return __utils__.findAll("h3.r").length >= 10;
96 }, "google search for \"casperjs\" retrieves 10 or more results");
97 });
98
99 casper.run(function() {
100 test.done();
101 });
102 });
103
104 Now run the tests suite:
105
106 .. code-block:: text
107
108 $ casperjs test googletesting.js
109
110 You'll probably get something like this:
111
112 .. figure:: _static/images/testsuiteok.png
113 :align: center
114
115
116 Advanced techniques
117 -------------------
118
119 The :ref:`Tester#begin() <tester_begin>` accepts either a function or an object to describe a suite; the object option allows to set up ``setUp()`` and ``tearDown()`` functions::
120
121 // cow-test.js
122 casper.test.begin('Cow can moo', 2, {
123 setUp: function(test) {
124 this.cow = new Cow();
125 },
126
127 tearDown: function(test) {
128 this.cow.destroy();
129 },
130
131 test: function(test) {
132 test.assertEquals(this.cow.moo(), 'moo!');
133 test.assert(this.cow.mowed);
134 test.done();
135 }
136 });
137
138
139 Test command args and options
140 -----------------------------
141
142 Arguments
143 ~~~~~~~~~
144
145 The ``capserjs test`` command will treat every passed argument as file or directory paths containing tests. It will recursively scan any passed directory to search for ``*.js`` or ``*.coffee`` files and add them to the stack.
146
147 .. warning ::
148
149 There are two important conditions when writing tests:
150
151 - You **must not** create a new ``Casper`` instance in a test file;
152 - You **must** call ``Tester.done()`` when all the tests contained in a suite (or in a file) have been executed.
153
154 Options
155 ~~~~~~~
156
157 Options are prefixed with a double-dash (``--``):
158
159 - ``--xunit=<filename>`` will export test suite results in a :ref:`XUnit XML file <xunit_report>`
160 - ``--direct`` will print :doc:`log messages <logging>` directly to the console
161 - ``--log-level=<logLevel>`` sets the logging level (see the :doc:`related section <logging>`)
162
163 .. versionadded:: 1.0
164
165 - ``--includes=foo.js,bar.js`` will include the ``foo.js`` and ``bar.js`` files before each test file execution;
166 - ``--pre=pre-test.js`` will add the tests contained in ``pre-test.js`` **before** executing the whole test suite;
167 - ``--post=post-test.js`` will add the tests contained in ``post-test.js`` **after** having executed the whole test suite;
168 - ``--fail-fast`` will terminate the current test suite as soon as a first failure is encountered.
169
170 Sample custom command:
171
172 .. code-block:: text
173
174 $ casperjs test --includes=foo.js,bar.js \
175 --pre=pre-test.js \
176 --post=post-test.js \
177 --direct \
178 --log-level=debug \
179 --fail-fast \
180 test1.js test2.js /path/to/some/test/dir
181
182 .. hint::
183
184 A `demo gist <https://gist.github.com/3813361>`_ is also available in order to get you started with a sample suite involving some of these options.
185
186
187 .. _xunit_report:
188
189 .. index:: XUnit, XML, Jenkins, Continuous Integration
190
191 Exporting results in XUnit format
192 ---------------------------------
193
194 CasperJS can export the results of the test suite to an XUnit XML file, which is compatible with continuous integration tools such as `Jenkins <http://jenkins-ci.org/>`_. To save the XUnit log of your test suite, use the ``--xunit`` option:
195
196 .. code-block:: text
197
198 $ casperjs test googletesting.js --save=log.xml
199
200 You should get a pretty XUnit XML report like this:
201
202 .. code-block:: xml
203
204 <?xml version="1.0" encoding="UTF-8"?>
205 <testsuites duration="1.249">
206 <testsuite errors="0" failures="0" name="Google search retrieves 10 or more results" package="googletesting" tests="5" time="1.249" timestamp="2012-12-30T21:27:26.320Z">
207 <testcase classname="googletesting" name="google homepage title is the one expected" time="0.813"/>
208 <testcase classname="googletesting" name="main form is found" time="0.002"/>
209 <testcase classname="googletesting" name="google title is ok" time="0.416"/>
210 <testcase classname="googletesting" name="search term has been submitted" time="0.017"/>
211 <testcase classname="googletesting" name="google search for &quot;casperjs&quot; retrieves 10 or more results" time="0.001"/>
212 <system-out/>
213 </testsuite>
214 </testsuites>
215
216 CasperJS own tests
217 ------------------
218
219 CasperJS has its own unit and functional test suite, located in the ``tests`` subfolder. To run this test suite:
220
221 .. code-block:: text
222
223 $ casperjs selftest
224
225 .. note::
226
227 Running this test suite is a great way to find any bug on your platform. If it fails, feel free to `file an issue <https://github.com/n1k0/casperjs/issues/new>`_ or to ask on the `CasperJS mailing-list <https://groups.google.com/forum/#!forum/casperjs>`_.
228
229
230 .. index:: extending
231
232 Extending Casper for Testing
233 ----------------------------
234
235 This command:
236
237 .. code-block:: text
238
239 $ casperjs test [path]
240
241 is just a shortcut for this one:
242
243 .. code-block:: text
244
245 $ casper /path/to/casperjs/tests/run.js [path]
246
247 So if you want to extend Casper capabilities for your tests, your best bet is to write your own runner and extend the casper object instance from there.
248
249 .. hint::
250
251 You can find the default runner code in `run.js <https://github.com/n1k0/casperjs/blob/master/tests/run.js>`_.
1 Upgrading to 1.1
2 ================
3
4 The most visible change is the way you write tests. With 1.0, you were able to access a ``.test`` property from any casper script and so running a suite using the standard ``casperjs`` executable::
5
6 // 1.0 style test script not using the `casperjs test` subcommand
7 var casper = require('casper').create();
8
9 casper.start('http://foo.bar/', function() {
10 this.test.assert(true);
11 });
12
13 casper.run(function() {
14 this.test.done(1);
15 this.test.renderResults(true);
16 });
17
18 In 1.1, the test framework has been heavily refactored to decouple the tester from a casper instance as much as possible, so it's no more possible to run a test suite right from the standard ``casperjs`` command as you would have done with the script shown above.
19
20 Instead you now have to use the :doc:`casperjs test <../testing>` subcommand mandatorily to access a tester instance from the ``casper.test`` property.
21
22 .. warning::
23
24 As of 1.1:
25
26 - you shouldn't invoke the ``renderResults()`` method directly anymore
27 - you shouldn't use the ``done()`` first argument to set planned test as it's been deprecated
28 - you can't access the ``casper.test`` property when not using the ``casperjs test`` subcommand
29
30 If you try, you'll get an error::
31
32 // test.js
33 var casper = require('casper').create();
34 casper.test.assert(true);
35
36 Will give:
37
38 .. code-block:: text
39
40 $ casperjs test.js
41 CasperError: casper.test property is only available using the `casperjs test` command
42
43 The new ``Tester#begin()`` method
44 ---------------------------------
45
46 However, a new :ref:`begin() <tester_begin>` method as been added to the :ref:`Tester <tester_module>` prototype, to ease describing your tests::
47
48 casper.test.begin('Description of my test', 1, function(test) {
49 test.assert(true);
50 test.done();
51 });
52
53 More asynchronously::
54
55 casper.test.begin('Description of my test', 1, function(test) {
56 casper.start('http://foo.bar/', function() {
57 test.assert(true);
58 });
59
60 casper.run(function() {
61 test.done();
62 });
63 });
64
65 .. note::
66
67 Please note that ``begin()``'s the second argument which is now the place to set the number of planned tests.
1 Upgrading
2 =========
3
4 .. toctree::
5 :maxdepth: 1
6
7 1.1
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 uses 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 From your root casper script::
28
29 var universe = require('./universe');
30 console.log(universe.answer()); // prints "It's 42"