casperjs 1.0.0.RC1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (121) hide show
  1. data/CHANGELOG.md +289 -1
  2. data/CONTRIBUTING.md +93 -0
  3. data/CONTRIBUTORS.md +53 -0
  4. data/README.md +29 -1
  5. data/batchbin/casperjs.bat +5 -0
  6. data/bin/bootstrap.js +164 -114
  7. data/bin/casperjs +84 -0
  8. data/bin/usage.txt +2 -1
  9. data/casperjs.gemspec +7 -4
  10. data/modules/casper.js +661 -239
  11. data/modules/clientutils.js +240 -54
  12. data/modules/colorizer.js +2 -1
  13. data/modules/events.js +13 -1
  14. data/modules/http.js +70 -0
  15. data/modules/mouse.js +1 -2
  16. data/modules/pagestack.js +166 -0
  17. data/modules/tester.js +1013 -659
  18. data/modules/utils.js +519 -367
  19. data/modules/vendors/coffee-script.js +2 -2
  20. data/modules/xunit.js +56 -24
  21. data/package.json +2 -2
  22. data/rpm/casperjs.spec +203 -0
  23. data/rpm/mkrpm.sh +25 -0
  24. data/rubybin/casperjs +9 -4
  25. data/samples/bbcshots.coffee +11 -10
  26. data/samples/bbcshots.js +16 -15
  27. data/samples/cliplay.js +3 -0
  28. data/samples/customevents.js +3 -0
  29. data/samples/customlogging.coffee +17 -19
  30. data/samples/customlogging.js +26 -27
  31. data/samples/download.js +4 -1
  32. data/samples/dynamic.js +3 -0
  33. data/samples/each.js +3 -0
  34. data/samples/events.js +4 -2
  35. data/samples/extends.js +4 -1
  36. data/samples/googlelinks.coffee +4 -1
  37. data/samples/googlelinks.js +10 -3
  38. data/samples/googlematch.coffee +1 -1
  39. data/samples/googlematch.js +5 -2
  40. data/samples/googlepagination.js +4 -1
  41. data/samples/googletesting.js +3 -0
  42. data/samples/logcolor.js +3 -0
  43. data/samples/metaextract.js +3 -0
  44. data/samples/multirun.js +3 -0
  45. data/samples/screenshot.js +4 -1
  46. data/samples/statushandlers.js +4 -1
  47. data/samples/steptimeout.js +3 -0
  48. data/samples/timeout.js +4 -1
  49. data/samples/translate.coffee +23 -0
  50. data/samples/translate.js +30 -0
  51. data/tests/commands/mytest.js +14 -0
  52. data/tests/commands/script.js +3 -0
  53. data/tests/run.js +82 -37
  54. data/tests/sample_modules/config.json +1 -0
  55. data/tests/sample_modules/csmodule.coffee +1 -0
  56. data/tests/sample_modules/jsmodule.js +1 -0
  57. data/tests/selftest.js +57 -0
  58. data/tests/site/dummy.js +1 -0
  59. data/tests/site/field-array.html +14 -0
  60. data/tests/site/frame1.html +10 -0
  61. data/tests/site/frame2.html +11 -0
  62. data/tests/site/frame3.html +11 -0
  63. data/tests/site/frames.html +12 -0
  64. data/tests/site/global.html +6 -1
  65. data/tests/site/includes/include1.js +6 -0
  66. data/tests/site/includes/include2.js +6 -0
  67. data/tests/site/index.html +3 -0
  68. data/tests/site/popup.html +19 -0
  69. data/tests/site/resources.html +7 -8
  70. data/tests/site/urls.html +14 -0
  71. data/tests/suites/casper/agent.js +3 -1
  72. data/tests/suites/casper/alert.js +14 -0
  73. data/tests/suites/casper/auth.js +24 -0
  74. data/tests/suites/casper/capture.js +12 -12
  75. data/tests/suites/casper/click.js +11 -1
  76. data/tests/suites/casper/confirm.js +24 -16
  77. data/tests/suites/casper/debug.js +10 -0
  78. data/tests/suites/casper/elementattribute.js +3 -1
  79. data/tests/suites/casper/encode.js +6 -2
  80. data/tests/suites/casper/evaluate.js +78 -18
  81. data/tests/suites/casper/events.js +3 -1
  82. data/tests/suites/casper/exists.js +3 -1
  83. data/tests/suites/casper/fetchtext.js +3 -1
  84. data/tests/suites/casper/flow.coffee +1 -1
  85. data/tests/suites/casper/formfill.js +39 -4
  86. data/tests/suites/casper/frames.js +43 -0
  87. data/tests/suites/casper/global.js +9 -3
  88. data/tests/suites/casper/headers.js +41 -0
  89. data/tests/suites/casper/history.js +3 -1
  90. data/tests/suites/casper/hooks.js +3 -1
  91. data/tests/suites/casper/keys.js +15 -0
  92. data/tests/suites/casper/location.js +21 -0
  93. data/tests/suites/casper/logging.js +3 -1
  94. data/tests/suites/casper/mouseevents.js +3 -1
  95. data/tests/suites/casper/onerror.js +3 -1
  96. data/tests/suites/casper/open.js +63 -1
  97. data/tests/suites/casper/popup.js +86 -0
  98. data/tests/suites/casper/prompt.js +11 -15
  99. data/tests/suites/casper/request.js +36 -0
  100. data/tests/suites/casper/resources.coffee +5 -5
  101. data/tests/suites/casper/scripts.js +32 -0
  102. data/tests/suites/casper/start.js +3 -1
  103. data/tests/suites/casper/steps.js +4 -2
  104. data/tests/suites/casper/urls.js +21 -0
  105. data/tests/suites/casper/viewport.js +3 -1
  106. data/tests/suites/casper/visible.js +3 -1
  107. data/tests/suites/casper/wait.js +22 -12
  108. data/tests/suites/casper/xpath.js +3 -1
  109. data/tests/suites/cli.js +3 -1
  110. data/tests/suites/clientutils.js +57 -3
  111. data/tests/suites/coffee.coffee +1 -1
  112. data/tests/suites/fs.js +3 -1
  113. data/tests/suites/http_status.js +19 -3
  114. data/tests/suites/popup.js +33 -0
  115. data/tests/suites/require.js +31 -0
  116. data/tests/suites/tester.js +134 -29
  117. data/tests/suites/utils.js +108 -8
  118. data/tests/suites/xunit.js +37 -6
  119. metadata +49 -15
  120. data/modules/injector.js +0 -93
  121. data/tests/suites/injector.js +0 -64
@@ -0,0 +1,5 @@
1
+ @ECHO OFF
2
+ set CASPER_PATH=%~dp0..
3
+ set CASPER_BIN=%CASPER_PATH%\bin\
4
+ set ARGV=%*
5
+ call phantomjs "%CASPER_BIN%bootstrap.js" --casper-path="%CASPER_PATH%" --cli %ARGV%
@@ -29,14 +29,155 @@
29
29
  */
30
30
 
31
31
  /*global console phantom require*/
32
+ /*jshint maxstatements:30 maxcomplexity:10*/
32
33
 
33
- if (!phantom || phantom.version.major !== 1 || phantom.version.minor < 5) {
34
- console.error('CasperJS needs at least PhantomJS v1.5.0');
34
+ if (!phantom) {
35
+ console.error('CasperJS needs to be executed in a PhantomJS environment http://phantomjs.org/');
35
36
  phantom.exit(1);
36
37
  }
37
38
 
38
- (function bootstrap(global) {
39
+ if (phantom.version.major === 1 && phantom.version.minor < 7) {
40
+ console.error('CasperJS needs at least PhantomJS v1.7 or later.');
41
+ phantom.exit(1);
42
+ } else {
43
+ bootstrap(window);
44
+ }
45
+
46
+ // Polyfills
47
+ if (typeof Function.prototype.bind !== "function") {
48
+ Function.prototype.bind = function(scope) {
49
+ "use strict";
50
+ var _function = this;
51
+ return function() {
52
+ return _function.apply(scope, arguments);
53
+ };
54
+ };
55
+ }
56
+
57
+ /**
58
+ * CasperJS ships with its own implementation of CommonJS' require() because
59
+ * PhantomJS' native one doesn't allow to specify supplementary, alternative
60
+ * lookup directories to fetch modules from.
61
+ *
62
+ */
63
+ function patchRequire(require, requireDirs) {
64
+ "use strict";
65
+ require('webserver'); // force generation of phantomjs' require.cache for the webserver module
66
+ var fs = require('fs');
67
+ var phantomBuiltins = ['fs', 'webpage', 'system', 'webserver'];
68
+ var phantomRequire = phantom.__orig__require = require;
69
+ var requireCache = {};
70
+ function possiblePaths(path, requireDir) {
71
+ var dir, paths = [];
72
+ if (path[0] === '.') {
73
+ paths.push.apply(paths, [
74
+ fs.absolute(path),
75
+ fs.absolute(fs.pathJoin(requireDir, path))
76
+ ]);
77
+ } else if (path[0] === '/') {
78
+ paths.push(path);
79
+ } else {
80
+ dir = fs.absolute(requireDir);
81
+ while (dir !== '' && dir.lastIndexOf(':') !== dir.length - 1) {
82
+ paths.push(fs.pathJoin(dir, 'modules', path));
83
+ // nodejs compatibility
84
+ paths.push(fs.pathJoin(dir, 'node_modules', path));
85
+ dir = fs.dirname(dir);
86
+ }
87
+ paths.push(fs.pathJoin(requireDir, 'lib', path));
88
+ paths.push(fs.pathJoin(requireDir, 'modules', path));
89
+ }
90
+ return paths;
91
+ }
92
+ var patchedRequire = function _require(path) {
93
+ var i, paths = [],
94
+ fileGuesses = [],
95
+ file,
96
+ module = {
97
+ exports: {}
98
+ };
99
+ if (phantomBuiltins.indexOf(path) !== -1) {
100
+ return phantomRequire(path);
101
+ }
102
+ requireDirs.forEach(function(requireDir) {
103
+ paths = paths.concat(possiblePaths(path, requireDir));
104
+ });
105
+ paths.forEach(function _forEach(testPath) {
106
+ fileGuesses.push.apply(fileGuesses, [
107
+ testPath,
108
+ testPath + '.js',
109
+ testPath + '.json',
110
+ testPath + '.coffee',
111
+ fs.pathJoin(testPath, 'index.js'),
112
+ fs.pathJoin(testPath, 'index.json'),
113
+ fs.pathJoin(testPath, 'index.coffee'),
114
+ fs.pathJoin(testPath, 'lib', fs.basename(testPath) + '.js'),
115
+ fs.pathJoin(testPath, 'lib', fs.basename(testPath) + '.json'),
116
+ fs.pathJoin(testPath, 'lib', fs.basename(testPath) + '.coffee')
117
+ ]);
118
+ });
119
+ file = null;
120
+ for (i = 0; i < fileGuesses.length && !file; ++i) {
121
+ if (fs.isFile(fileGuesses[i])) {
122
+ file = fileGuesses[i];
123
+ }
124
+ }
125
+ if (!file) {
126
+ throw new window.CasperError("CasperJS couldn't find module " + path);
127
+ }
128
+ if (file in requireCache) {
129
+ return requireCache[file].exports;
130
+ }
131
+ if (/\.json/i.test(file)) {
132
+ var parsed = JSON.parse(fs.read(file));
133
+ requireCache[file] = parsed;
134
+ return parsed;
135
+ }
136
+ var scriptCode = (function getScriptCode(file) {
137
+ var scriptCode = fs.read(file);
138
+ if (/\.coffee$/i.test(file)) {
139
+ /*global CoffeeScript*/
140
+ scriptCode = CoffeeScript.compile(scriptCode);
141
+ }
142
+ return scriptCode;
143
+ })(file);
144
+ var fn = new Function('__file__', 'require', 'module', 'exports', scriptCode);
145
+ try {
146
+ fn(file, _require, module, module.exports);
147
+ } catch (e) {
148
+ var error = new window.CasperError('__mod_error(' + path + ':' + e.line + '):: ' + e);
149
+ error.file = file;
150
+ error.line = e.line;
151
+ error.stack = e.stack;
152
+ error.stackArray = JSON.parse(JSON.stringify(e.stackArray));
153
+ if (error.stackArray.length > 0) {
154
+ error.stackArray[0].sourceURL = file;
155
+ }
156
+ throw error;
157
+ }
158
+ requireCache[file] = module;
159
+ return module.exports;
160
+ };
161
+ patchedRequire.patched = true;
162
+ return patchedRequire;
163
+ }
164
+
165
+ function bootstrap(global) {
39
166
  "use strict";
167
+ var phantomArgs = require('system').args;
168
+
169
+ /**
170
+ * Hooks in default phantomjs error handler to print a hint when a possible
171
+ * casperjs command misuse is detected.
172
+ *
173
+ */
174
+ phantom.onError = function onPhantomError(msg, trace) {
175
+ phantom.defaultErrorHandler.apply(phantom, arguments);
176
+ if (msg.indexOf("ReferenceError: Can't find variable: casper") === 0) {
177
+ console.error('Hint: you may want to use the `casperjs test` command.');
178
+ }
179
+ };
180
+
40
181
  /**
41
182
  * Loads and initialize the CasperJS environment.
42
183
  */
@@ -93,12 +234,6 @@ if (!phantom || phantom.version.major !== 1 || phantom.version.minor < 5) {
93
234
  // custom global CasperError
94
235
  global.CasperError = function CasperError(msg) {
95
236
  Error.call(this);
96
- try {
97
- // let's get where this error has been thrown from, if we can
98
- this._from = arguments.callee.caller.name;
99
- } catch (e) {
100
- this._from = "anonymous";
101
- }
102
237
  this.message = msg;
103
238
  this.name = 'CasperError';
104
239
  };
@@ -120,7 +255,7 @@ if (!phantom || phantom.version.major !== 1 || phantom.version.minor < 5) {
120
255
  throw new global.CasperError('Cannot read package file contents: ' + e);
121
256
  }
122
257
  parts = pkg.version.trim().split(".");
123
- if (parts < 3) {
258
+ if (parts.length < 3) {
124
259
  throw new global.CasperError("Invalid version number");
125
260
  }
126
261
  patchPart = parts[2].split('-');
@@ -139,100 +274,11 @@ if (!phantom || phantom.version.major !== 1 || phantom.version.minor < 5) {
139
274
  };
140
275
  })(phantom.casperPath);
141
276
 
142
- /**
143
- * Retrieves the javascript source code from a given .js or .coffee file.
144
- *
145
- * @param String file The path to the file
146
- * @param Function|null onError An error callback (optional)
147
- */
148
- phantom.getScriptCode = function getScriptCode(file, onError) {
149
- var scriptCode = fs.read(file);
150
- if (/\.coffee$/i.test(file)) {
151
- /*global CoffeeScript*/
152
- scriptCode = CoffeeScript.compile(scriptCode);
153
- }
154
- return scriptCode;
155
- };
156
-
157
- /**
158
- * Patching require() to allow loading of other modules than PhantomJS'
159
- * builtin ones.
160
- * Inspired by phantomjs-nodify: https://github.com/jgonera/phantomjs-nodify/
161
- * TODO: remove when PhantomJS has full module support
162
- */
163
- require = (function _require(require, requireDir) {
164
- var phantomBuiltins = ['fs', 'webpage', 'webserver', 'system'];
165
- var phantomRequire = phantom.__orig__require = require;
166
- var requireCache = {};
167
- return function _require(path) {
168
- var i, dir, paths = [],
169
- fileGuesses = [],
170
- file,
171
- module = {
172
- exports: {}
173
- };
174
- if (phantomBuiltins.indexOf(path) !== -1) {
175
- return phantomRequire(path);
176
- }
177
- if (path[0] === '.') {
178
- paths.push.apply(paths, [
179
- fs.absolute(path),
180
- fs.absolute(fs.pathJoin(requireDir, path))
181
- ]);
182
- } else if (path[0] === '/') {
183
- paths.push(path);
184
- } else {
185
- dir = fs.absolute(requireDir);
186
- while (dir !== '' && dir.lastIndexOf(':') !== dir.length - 1) {
187
- // nodejs compatibility
188
- paths.push(fs.pathJoin(dir, 'node_modules', path));
189
- dir = fs.dirname(dir);
190
- }
191
- paths.push(fs.pathJoin(requireDir, 'lib', path));
192
- paths.push(fs.pathJoin(requireDir, 'modules', path));
193
- }
194
- paths.forEach(function _forEach(testPath) {
195
- fileGuesses.push.apply(fileGuesses, [
196
- testPath,
197
- testPath + '.js',
198
- testPath + '.coffee',
199
- fs.pathJoin(testPath, 'index.js'),
200
- fs.pathJoin(testPath, 'index.coffee'),
201
- fs.pathJoin(testPath, 'lib', fs.basename(testPath) + '.js'),
202
- fs.pathJoin(testPath, 'lib', fs.basename(testPath) + '.coffee')
203
- ]);
204
- });
205
- file = null;
206
- for (i = 0; i < fileGuesses.length && !file; ++i) {
207
- if (fs.isFile(fileGuesses[i])) {
208
- file = fileGuesses[i];
209
- }
210
- }
211
- if (!file) {
212
- throw new Error("CasperJS couldn't find module " + path);
213
- }
214
- if (file in requireCache) {
215
- return requireCache[file].exports;
216
- }
217
- var scriptCode = phantom.getScriptCode(file);
218
- var fn = new Function('__file__', 'require', 'module', 'exports', scriptCode);
219
- try {
220
- fn(file, _require, module, module.exports);
221
- } catch (e) {
222
- var error = new global.CasperError('__mod_error(' + path + '):: ' + e);
223
- error.file = file;
224
- throw error;
225
- }
226
- requireCache[file] = module;
227
- return module.exports;
228
- };
229
- })(require, phantom.casperPath);
230
-
231
- // BC < 0.6
232
- phantom.Casper = require('casper').Casper;
277
+ // patch require
278
+ global.require = patchRequire(global.require, [phantom.casperPath, fs.workingDirectory]);
233
279
 
234
280
  // casper cli args
235
- phantom.casperArgs = require('cli').parse(phantom.args);
281
+ phantom.casperArgs = global.require('cli').parse(phantom.args);
236
282
 
237
283
  // loaded status
238
284
  phantom.casperLoaded = true;
@@ -243,13 +289,23 @@ if (!phantom || phantom.version.major !== 1 || phantom.version.minor < 5) {
243
289
  */
244
290
  phantom.initCasperCli = function initCasperCli() {
245
291
  var fs = require("fs");
292
+ var baseTestsPath = fs.pathJoin(phantom.casperPath, 'tests');
246
293
 
247
294
  if (!!phantom.casperArgs.options.version) {
248
295
  console.log(phantom.casperVersion.toString());
249
- phantom.exit(0);
296
+ return phantom.exit();
250
297
  } else if (phantom.casperArgs.get(0) === "test") {
251
- phantom.casperScript = fs.absolute(fs.pathJoin(phantom.casperPath, 'tests', 'run.js'));
298
+ phantom.casperScript = fs.absolute(fs.pathJoin(baseTestsPath, 'run.js'));
299
+ phantom.casperTest = true;
252
300
  phantom.casperArgs.drop("test");
301
+ } else if (phantom.casperArgs.get(0) === "selftest") {
302
+ phantom.casperScript = fs.absolute(fs.pathJoin(baseTestsPath, 'run.js'));
303
+ phantom.casperSelfTest = phantom.casperTest = true;
304
+ phantom.casperArgs.options.includes = fs.pathJoin(baseTestsPath, 'selftest.js');
305
+ if (phantom.casperArgs.args.length <= 1) {
306
+ phantom.casperArgs.args.push(fs.pathJoin(baseTestsPath, 'suites'));
307
+ }
308
+ phantom.casperArgs.drop("selftest");
253
309
  } else if (phantom.casperArgs.args.length === 0 || !!phantom.casperArgs.options.help) {
254
310
  var phantomVersion = [phantom.version.major, phantom.version.minor, phantom.version.patch].join('.');
255
311
  var f = require("utils").format;
@@ -257,17 +313,16 @@ if (!phantom || phantom.version.major !== 1 || phantom.version.minor < 5) {
257
313
  phantom.casperVersion.toString(),
258
314
  phantom.casperPath, phantomVersion));
259
315
  console.log(fs.read(fs.pathJoin(phantom.casperPath, 'bin', 'usage.txt')));
260
- phantom.exit(0);
316
+ return phantom.exit(0);
261
317
  }
262
318
 
263
-
264
319
  if (!phantom.casperScript) {
265
320
  phantom.casperScript = phantom.casperArgs.get(0);
266
321
  }
267
322
 
268
323
  if (!fs.isFile(phantom.casperScript)) {
269
324
  console.error('Unable to open file: ' + phantom.casperScript);
270
- phantom.exit(1);
325
+ return phantom.exit(1);
271
326
  }
272
327
 
273
328
  // filter out the called script name from casper args
@@ -278,15 +333,10 @@ if (!phantom || phantom.version.major !== 1 || phantom.version.minor < 5) {
278
333
  };
279
334
 
280
335
  if (!phantom.casperLoaded) {
281
- try {
282
- phantom.loadCasper();
283
- } catch (e) {
284
- console.error("Unable to load casper environment: " + e);
285
- phantom.exit();
286
- }
336
+ phantom.loadCasper();
287
337
  }
288
338
 
289
339
  if (true === phantom.casperArgs.get('cli')) {
290
340
  phantom.initCasperCli();
291
341
  }
292
- })(window);
342
+ }
@@ -0,0 +1,84 @@
1
+ #!/usr/bin/env python
2
+
3
+ import json
4
+ import os
5
+ import subprocess
6
+ import sys
7
+
8
+ def test_cmd(cmd):
9
+ try:
10
+ return subprocess.check_output([__file__] + cmd.split(' '))
11
+ except subprocess.CalledProcessError as err:
12
+ sys.stderr.write('FAIL: %s\n' % ' '.join(err.cmd))
13
+ sys.stderr.write(' %s\n' % err.output)
14
+ sys.exit(1)
15
+
16
+ def resolve(path):
17
+ if os.path.islink(path):
18
+ path = os.path.join(os.path.dirname(path), os.readlink(path))
19
+ return resolve(path)
20
+ return path
21
+
22
+ PHANTOMJS_NATIVE_ARGS = [
23
+ 'cookies-file',
24
+ 'config',
25
+ 'debug',
26
+ 'disk-cache',
27
+ 'ignore-ssl-errors',
28
+ 'load-images',
29
+ 'load-plugins',
30
+ 'local-storage-path',
31
+ 'local-storage-quota',
32
+ 'local-to-remote-url-access',
33
+ 'max-disk-cache-size',
34
+ 'output-encoding',
35
+ 'proxy',
36
+ 'proxy-auth',
37
+ 'proxy-type',
38
+ 'remote-debugger-port',
39
+ 'remote-debugger-autorun',
40
+ 'script-encoding',
41
+ 'web-security',
42
+ ]
43
+ CASPER_ARGS = []
44
+ CASPER_PATH = os.path.abspath(os.path.join(os.path.dirname(resolve(__file__)), '..'))
45
+ PHANTOMJS_ARGS = []
46
+ SYS_ARGS = sys.argv[1:]
47
+
48
+ if len(SYS_ARGS) and SYS_ARGS[0] == '__selfcommandtest':
49
+ print('Starting Python executable tests...')
50
+ pkg_version = json.loads(open('package.json').read()).get('version')
51
+ scripts_path = os.path.join(CASPER_PATH, 'tests', 'commands')
52
+ assert(test_cmd('--help').find(pkg_version) > -1)
53
+ assert(test_cmd('--version').strip() == pkg_version)
54
+ assert(test_cmd(os.path.join(scripts_path, 'script.js')) == 'it works\n')
55
+ test_output = test_cmd('test --no-colors ' + os.path.join(scripts_path, 'mytest.js'))
56
+ assert('PASS ok1' in test_output)
57
+ assert('PASS ok2' in test_output)
58
+ assert('PASS ok3' in test_output)
59
+ print('Python executable tests passed.')
60
+ sys.exit(0)
61
+
62
+ for arg in SYS_ARGS:
63
+ found = False
64
+ for native in PHANTOMJS_NATIVE_ARGS:
65
+ if arg.startswith('--%s' % native):
66
+ PHANTOMJS_ARGS.append(arg)
67
+ found = True
68
+ if not found:
69
+ CASPER_ARGS.append(arg)
70
+
71
+ CASPER_COMMAND = os.environ.get('PHANTOMJS_EXECUTABLE', 'phantomjs').split(' ')
72
+ CASPER_COMMAND.extend(PHANTOMJS_ARGS)
73
+ CASPER_COMMAND.extend([
74
+ os.path.join(CASPER_PATH, 'bin', 'bootstrap.js'),
75
+ '--casper-path=%s' % CASPER_PATH,
76
+ '--cli'
77
+ ])
78
+ CASPER_COMMAND.extend(CASPER_ARGS)
79
+
80
+ try:
81
+ os.execvp(CASPER_COMMAND[0], CASPER_COMMAND)
82
+ except OSError as err:
83
+ print(('Fatal: %s; did you install phantomjs?' % err))
84
+ sys.exit(1)
@@ -1,10 +1,11 @@
1
1
 
2
2
  Usage: casperjs [options] script.[js|coffee] [script argument [script argument ...]]
3
3
  casperjs [options] test [test path [test path ...]]
4
+ casperjs [options] selftest
4
5
 
5
6
  Options:
6
7
 
7
8
  --help Prints this help
8
9
  --version Prints out CasperJS version
9
10
 
10
- Read the docs http://casperjs.org/
11
+ Read the docs http://casperjs.org/