casperjs 1.0.0.RC1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (125) hide show
  1. data/CHANGELOG.md +179 -0
  2. data/LICENSE.md +19 -0
  3. data/README.md +30 -0
  4. data/bin/bootstrap.js +292 -0
  5. data/bin/usage.txt +10 -0
  6. data/casperjs.gemspec +21 -0
  7. data/modules/casper.js +1679 -0
  8. data/modules/cli.js +138 -0
  9. data/modules/clientutils.js +595 -0
  10. data/modules/colorizer.js +129 -0
  11. data/modules/events.js +247 -0
  12. data/modules/injector.js +93 -0
  13. data/modules/mouse.js +110 -0
  14. data/modules/querystring.js +187 -0
  15. data/modules/tester.js +807 -0
  16. data/modules/utils.js +429 -0
  17. data/modules/vendors/coffee-script.js +8 -0
  18. data/modules/xunit.js +123 -0
  19. data/package.json +35 -0
  20. data/rubybin/casperjs +57 -0
  21. data/samples/bbcshots.coffee +64 -0
  22. data/samples/bbcshots.js +80 -0
  23. data/samples/cliplay.coffee +19 -0
  24. data/samples/cliplay.js +21 -0
  25. data/samples/customevents.coffee +11 -0
  26. data/samples/customevents.js +13 -0
  27. data/samples/customlogging.coffee +33 -0
  28. data/samples/customlogging.js +42 -0
  29. data/samples/download.coffee +10 -0
  30. data/samples/download.js +11 -0
  31. data/samples/dynamic.coffee +60 -0
  32. data/samples/dynamic.js +65 -0
  33. data/samples/each.coffee +14 -0
  34. data/samples/each.js +17 -0
  35. data/samples/events.coffee +34 -0
  36. data/samples/events.js +41 -0
  37. data/samples/extends.coffee +29 -0
  38. data/samples/extends.js +37 -0
  39. data/samples/googlelinks.coffee +27 -0
  40. data/samples/googlelinks.js +33 -0
  41. data/samples/googlematch.coffee +47 -0
  42. data/samples/googlematch.js +65 -0
  43. data/samples/googlepagination.coffee +40 -0
  44. data/samples/googlepagination.js +51 -0
  45. data/samples/googletesting.coffee +17 -0
  46. data/samples/googletesting.js +23 -0
  47. data/samples/logcolor.coffee +10 -0
  48. data/samples/logcolor.js +11 -0
  49. data/samples/metaextract.coffee +23 -0
  50. data/samples/metaextract.js +29 -0
  51. data/samples/multirun.coffee +37 -0
  52. data/samples/multirun.js +56 -0
  53. data/samples/screenshot.coffee +28 -0
  54. data/samples/screenshot.js +33 -0
  55. data/samples/statushandlers.coffee +15 -0
  56. data/samples/statushandlers.js +19 -0
  57. data/samples/steptimeout.coffee +37 -0
  58. data/samples/steptimeout.js +45 -0
  59. data/samples/timeout.coffee +39 -0
  60. data/samples/timeout.js +47 -0
  61. data/tests/run.js +76 -0
  62. data/tests/site/alert.html +10 -0
  63. data/tests/site/click.html +40 -0
  64. data/tests/site/confirm.html +12 -0
  65. data/tests/site/elementattribute.html +6 -0
  66. data/tests/site/error.html +10 -0
  67. data/tests/site/form.html +26 -0
  68. data/tests/site/global.html +9 -0
  69. data/tests/site/images/phantom.png +0 -0
  70. data/tests/site/index.html +17 -0
  71. data/tests/site/mouse-events.html +47 -0
  72. data/tests/site/multiple-forms.html +16 -0
  73. data/tests/site/page1.html +8 -0
  74. data/tests/site/page2.html +8 -0
  75. data/tests/site/page3.html +8 -0
  76. data/tests/site/prompt.html +12 -0
  77. data/tests/site/resources.html +16 -0
  78. data/tests/site/result.html +11 -0
  79. data/tests/site/test.html +10 -0
  80. data/tests/site/visible.html +17 -0
  81. data/tests/site/waitFor.html +22 -0
  82. data/tests/suites/casper/agent.js +24 -0
  83. data/tests/suites/casper/capture.js +31 -0
  84. data/tests/suites/casper/click.js +61 -0
  85. data/tests/suites/casper/confirm.js +21 -0
  86. data/tests/suites/casper/elementattribute.js +8 -0
  87. data/tests/suites/casper/encode.js +20 -0
  88. data/tests/suites/casper/evaluate.js +27 -0
  89. data/tests/suites/casper/events.js +38 -0
  90. data/tests/suites/casper/exists.js +9 -0
  91. data/tests/suites/casper/fetchtext.js +9 -0
  92. data/tests/suites/casper/flow.coffee +38 -0
  93. data/tests/suites/casper/formfill.js +69 -0
  94. data/tests/suites/casper/global.js +9 -0
  95. data/tests/suites/casper/history.js +21 -0
  96. data/tests/suites/casper/hooks.js +41 -0
  97. data/tests/suites/casper/logging.js +38 -0
  98. data/tests/suites/casper/mouseevents.js +27 -0
  99. data/tests/suites/casper/onerror.js +19 -0
  100. data/tests/suites/casper/open.js +73 -0
  101. data/tests/suites/casper/prompt.js +17 -0
  102. data/tests/suites/casper/resources.coffee +24 -0
  103. data/tests/suites/casper/start.js +15 -0
  104. data/tests/suites/casper/steps.js +32 -0
  105. data/tests/suites/casper/viewport.js +11 -0
  106. data/tests/suites/casper/visible.js +17 -0
  107. data/tests/suites/casper/wait.js +27 -0
  108. data/tests/suites/casper/xpath.js +32 -0
  109. data/tests/suites/cli.js +125 -0
  110. data/tests/suites/clientutils.js +84 -0
  111. data/tests/suites/coffee.coffee +19 -0
  112. data/tests/suites/fs.js +36 -0
  113. data/tests/suites/http_status.js +28 -0
  114. data/tests/suites/injector.js +64 -0
  115. data/tests/suites/tester.js +121 -0
  116. data/tests/suites/utils.js +209 -0
  117. data/tests/suites/xunit.js +16 -0
  118. data/tests/testdir/01_a/abc.js +0 -0
  119. data/tests/testdir/01_a/def.js +0 -0
  120. data/tests/testdir/02_b/abc.js +0 -0
  121. data/tests/testdir/03_a.js +0 -0
  122. data/tests/testdir/03_b.js +0 -0
  123. data/tests/testdir/04/01_init.js +0 -0
  124. data/tests/testdir/04/02_do.js +0 -0
  125. metadata +192 -0
@@ -0,0 +1,179 @@
1
+ CasperJS Changelog
2
+ ==================
3
+
4
+ XXXX-XX-XX, v1.0.0
5
+ ------------------
6
+
7
+ - fixed [#164](https://github.com/n1k0/casperjs/issues/164) - ability to force CLI parameters as strings (see [related documentation](http://casperjs.org/cli.html#raw)).
8
+
9
+ 2012-06-26, v1.0.0-RC1
10
+ ----------------------
11
+
12
+ ### PhantomJS 1.5 & 1.6
13
+
14
+ - fixed [#119](https://github.com/n1k0/casperjs/issues/119) - HTTP status wasn't properly caught
15
+ - fixed [#132](https://github.com/n1k0/casperjs/issues/132) - added ability to include js/coffee files using a dedicated option when using the [`casper test` command](http://casperjs.org/testing.html)
16
+ - fixed [#140](https://github.com/n1k0/casperjs/issues/140) - `casper test` now resolves local paths urls
17
+ - fixed [#148](https://github.com/n1k0/casperjs/issues/148) - [`utils.isWebPage()`](http://casperjs.org/api.html#utils.isWebPage) was broken
18
+ - fixed [#149](https://github.com/n1k0/casperjs/issues/149) - [`ClientUtils.fill()`](http://casperjs.org/api.html#casper.fill) was searching elements globally
19
+ - fixed [#154](https://github.com/n1k0/casperjs/issues/154) - firing the `change` event after a field value has been set
20
+ - fixed [#144](https://github.com/n1k0/casperjs/issues/144) - added a [`safeLogs` option](http://casperjs.org/api.html#casper.options) to blur password values in debug logs. **This option is set to `true` by default.**
21
+ - added [`Casper.userAgent()`](http://casperjs.org/api.html#casper.userAgent) to ease a more dynamic setting of user-agent string
22
+ - added [`Tester.assertTitleMatch()`](http://casperjs.org/api.html#tester.assertTitleMatch) method
23
+ - added [`utils.getPropertyPath()`](http://casperjs.org/api.html#utils.getPropertyPath)
24
+ - added [`Casper.captureBase64()`](http://casperjs.org/api.html#casper.captureBase64) for rendering screen captures as base64 strings - closes [#150](https://github.com/n1k0/casperjs/issues/150)
25
+ - added [`Casper.reload()`](http://casperjs.org/api.html#casper.reload)
26
+ - fixed failed test messages didn't expose the subject correctly
27
+ - switched to more standard `.textContent` property to get a node text; this allows a better compatibility of the clientutils bookmarklet with non-webkit browsers
28
+ - casper modules now all use [javascript strict mode](http://www.nczonline.net/blog/2012/03/13/its-time-to-start-using-javascript-strict-mode/)
29
+
30
+ ### PhantomJS >= 1.6 supported features
31
+
32
+ - added support of custom headers sending in outgoing request - refs [#137](https://github.com/n1k0/casperjs/issues/137))
33
+ - added support for `prompt()` and `confirm()` - closes [#125](https://github.com/n1k0/casperjs/issues/125)
34
+ - fixed [#157](https://github.com/n1k0/casperjs/issues/157) - added support for PhantomJS 1.6 `WebPage#zoomFactor`
35
+ - added `url.changed` & `navigation.requested` events - refs [#151](https://github.com/n1k0/casperjs/issues/151)
36
+
37
+ 2012-06-04, v0.6.10
38
+ -------------------
39
+
40
+ - fixed [#73](https://github.com/n1k0/casperjs/issues/73) - `Casper.download()` not working correctly with binaries
41
+ - fixed [#129](https://github.com/n1k0/casperjs/issues/129) - Can't put `//` comments in evaluate() function
42
+ - closed [#130](https://github.com/n1k0/casperjs/issues/130) - Added a `Dummy` [colorizer](http://casperjs.org/api.html#colorizer) class, in order to disable colors in console output
43
+ - fixed [#133](https://github.com/n1k0/casperjs/issues/133) - updated and fixed documentation about [extensibility](http://casperjs.org/extending.html)
44
+ - added `Casper.clickLabel()` for clicking on an element found by its `innerText` content
45
+
46
+ As a side note, the official website monolithic page has been split across several ones: http://casperjs.org/
47
+
48
+ 2012-05-29, v0.6.9
49
+ ------------------
50
+
51
+ - **BC BREAK:** PhantomJS 1.5 is now the minimal PhantomJS version supported.
52
+ - fixed [#114](https://github.com/n1k0/casperjs/issues/114) - ensured client-side utils are injected before any `evaluate()` call
53
+ - merged [#89](https://github.com/n1k0/casperjs/pull/89) - Support for more mouse events (@nrabinowitz)
54
+ - [added a new `error` event, better error reporting](https://github.com/n1k0/casperjs/commit/2e6988ae821b3251e063d11ba28af59b0683852a)
55
+ - fixed [#117](https://github.com/n1k0/casperjs/issues/117) - `fill()` coulnd't `submit()` a form with a submit input named *submit*
56
+ - merged [#122](https://github.com/n1k0/casperjs/pull/122) - allow downloads to be triggered by more than just `GET` requests
57
+ - closed [#57](https://github.com/n1k0/casperjs/issues/57) - added context to emitted test events + complete assertion framework refactor
58
+ - fixed loaded resources array is now reset adequately [reference discussion](https://groups.google.com/forum/?hl=fr?fromgroups#!topic/casperjs/TCkNzrj1IoA)
59
+ - fixed incomplete error message logged when passed an erroneous selector (xpath and css)
60
+
61
+ 2012-05-20, v0.6.8
62
+ ------------------
63
+
64
+ - added support for [XPath selectors](http://casperjs.org/#selectors)
65
+ - added `Tester.assertNotEquals()` ([@juliangruber](https://github.com/juliangruber))
66
+ - fixed [#109](https://github.com/n1k0/casperjs/issues/109) - CLI args containing `=` (equals sign) were not being parsed properly
67
+
68
+ 2012-05-12, v0.6.7
69
+ ------------------
70
+
71
+ - fixes [#107](https://github.com/n1k0/casperjs/issues/107): client utils were possibly not yet being injected and available when calling `Capser.base64encode()` from some events
72
+ - merged [PR #96](https://github.com/n1k0/casperjs/pull/96): make python launcher use `os.execvp()` instead of `subprocess.Popen()` ([@jart](https://github.com/jart)):
73
+ > This patch fixes a bug where casperjs' python launcher process won't pass along kill
74
+ > signals to the phantomjs subprocess. This patch works by using an exec system call
75
+ > which causes the phantomjs subprocess to completely replace the casperjs parent
76
+ > process (while maintaining the same pid). This patch also has the added benefit of
77
+ > saving 10 megs or so of memory because the python process is discarded.
78
+ - fixes [#109](https://github.com/n1k0/casperjs/issues/109) - CLI args containing `=` (equals sign) were not parsed properly
79
+ - fixes [#100](https://github.com/n1k0/casperjs/issues/100) & [#110](https://github.com/n1k0/casperjs/issues/110) - *googlepagination* sample was broken
80
+ - merged #103 - added `Tester.assertNotEquals` method (@juliangruber)
81
+
82
+ 2012-04-27, v0.6.6
83
+ ------------------
84
+
85
+ - **BC BREAK:**: moved the `page.initialized` event to where it should have always been, and is now using native phantomjs `onInitialized` event
86
+ - fixed [#95](https://github.com/n1k0/casperjs/issues/95) - `Tester.assertSelectorExists` was broken
87
+
88
+ 2012-03-28, v0.6.5
89
+ ------------------
90
+
91
+ - **BC BREAK:** reverted 8347278 (refs [#34](https://github.com/n1k0/casperjs/issues/34) and added a new `clear()` method to *close* a page
92
+ You now have to call `casper.clear()` if you want to stop javascript execution within the remote DOM environment.
93
+ - **BC BREAK:** removed `fallbackToHref` option handling in `ClientUtils.click()` (refs [#63](https://github.com/n1k0/casperjs/issues/63))
94
+ - `tester.findTestFiles()` now returns results in predictable order
95
+ - added `--log-level` and `--direct` options to `casper test` command
96
+ - fixed 0.6.4 version number in `bootstrap.js`
97
+ - centralized version number to package.json
98
+ - ensured compatibility with PhantomJS 1.5
99
+
100
+ 2012-02-09, v0.6.4
101
+ ------------------
102
+
103
+ - fixed `casperjs` command wasn't passing phantomjs native option in the correct order, resulting them not being taken into account by phantomjs engine:
104
+ - fixed [#49](https://github.com/n1k0/casperjs/issues/49) - `casperjs` is not sending `--ssl-ignore-errors`
105
+ - fixed [#50](https://github.com/n1k0/casperjs/issues/50) - Cookies not being set when passing `--cookies-file` option
106
+ - fixed Python3 compatibility of the `casperjs` executable
107
+
108
+ 2012-02-05, v0.6.3
109
+ ------------------
110
+
111
+ - fixed [#48](https://github.com/n1k0/casperjs/issues/48) - XML Output file doesn't have classpath populated with file name
112
+ - refs [#46](https://github.com/n1k0/casperjs/issues/46) - added value details to Tester `fail` event
113
+ - new site design, new [domain](http://casperjs.org/), enhanced & updated docs
114
+
115
+ 2012-01-19, v0.6.2
116
+ ------------------
117
+
118
+ - fixed [#41](https://github.com/n1k0/casperjs/issues/41) - injecting casperjs lib crashes `cmd.exe` on Windows 7
119
+ - fixed [#42](https://github.com/n1k0/casperjs/issues/42) - Use file name of test script as 'classname' in JUnit XML report (@mpeltonen)
120
+ - fixed [#43](https://github.com/n1k0/casperjs/issues/43) - Exit status not reported back to caller
121
+ - suppressed colorized output syntax for windows; was making output hard to read
122
+ - added patchy `fs.isWindows()` method
123
+ - added `--xunit=<filename>` cli option to `$ casperjs test` command for saving xunit results, eg.:
124
+
125
+ $ casperjs test tests/suites --xunit=build-result.xml
126
+
127
+
128
+ 2012-01-16, v0.6.1
129
+ ------------------
130
+
131
+ - restablished js-emulated click simulation first, then native QtWebKit
132
+ events as a fallback; some real world testing have surprinsingly proven the former being often
133
+ more efficient than the latter
134
+ - fixed casperjs executable could not handle a `PHANTOMJS_EXECUTABLE` containing spaces
135
+ - fixed casper could not be used without the executable [as documented](http://casperjs.org/#faq-executable)
136
+ - fixed wrong `debug` log level on `ClientUtils.click()` error; set to `error`
137
+
138
+ Please check the [updated documentation](http://casperjs.org).
139
+
140
+ 2012-01-12, v0.6.0
141
+ ------------------
142
+
143
+ - **BC BREAK:** `Casper.click()` now uses native Webkit mouse events instead of previous crazy utopic javascript emulation
144
+ - **BC BREAK:** All errors thrown by CasperJS core are of the new `CasperError` type
145
+ - **BC BREAK:** removed obsolete `replaceFunctionPlaceholders()`
146
+ - *Deprecated*: `Casper.extend()` method has been deprecated; use natural javascript extension mechanisms instead (see samples)
147
+ - added `$ casperjs test` command for running split test suites
148
+ - `Casper.open()` can now perform HTTP `GET`, `POST`, `PUT`, `DELETE` and `HEAD` operations
149
+ - commonjs/nodejs-like module exports implementation
150
+ - ported nodejs' `events` module to casperjs; lots of events added, plus some value filtering capabilities
151
+ - introduced the `mouse` module to handle native Webkit mouse events
152
+ - added support for `RegExp` input in `Casper.resourceExists()`
153
+ - added printing of source file path for any uncaught exception printed onto the console
154
+ - added an emulation of stack trace printing (but PhantomJS will have to upgrade its javascript engine for it to be fully working though)
155
+
156
+ Please check the [updated documentation](http://casperjs.org).
157
+
158
+ ---
159
+
160
+ 2011-12-25, v0.4.2
161
+ ------------------
162
+
163
+ - merged PR #30 - Add request method and request data to the `base64encode()` method (@jasonlfunk)
164
+ - `casperjs` executable now gracefully exists on KeyboardInterrupt
165
+ - added `Casper.download()` method, for downloading any resource and save it onto the filesystem
166
+
167
+ ---
168
+
169
+ 2011-12-21, v0.4.1
170
+ ------------------
171
+
172
+ - fixed #31 - replaced bash executable script by a Python one
173
+
174
+ ---
175
+
176
+ 2011-12-20, v0.4.0
177
+ ------------------
178
+
179
+ - first numbered version
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2011-2012 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.
@@ -0,0 +1,30 @@
1
+ # CasperJS [![Build Status](https://secure.travis-ci.org/n1k0/casperjs.png)](http://travis-ci.org/n1k0/casperjs)
2
+
3
+ CasperJS is a navigation scripting & testing utility for [PhantomJS](http://www.phantomjs.org/).
4
+ It eases the process of defining a full navigation scenario and provides useful
5
+ high-level functions, methods & syntaxic sugar for doing common tasks such as:
6
+
7
+ - defining & ordering [navigation steps](http://casperjs.org/quickstart.html)
8
+ - [filling forms](http://casperjs.org/api.html#casper.fill)
9
+ - [clicking links](http://casperjs.org/api.html#casper.click)
10
+ - [capturing screenshots](http://casperjs.org/api.html#casper.captureSelector) of a page (or an area)
11
+ - [making assertions on remote DOM](http://casperjs.org/api.html#tester)
12
+ - [logging](http://casperjs.org/logging.html) & [events](http://casperjs.org/events-filters.html)
13
+ - [downloading base64](http://casperjs.org/api.html#casper.download) encoded resources, even binary ones
14
+ - catching errors and react accordingly
15
+ - writing [functional test suites](http://casperjs.org/testing.html), exporting results as JUnit XML (xUnit)
16
+
17
+ Browse the [sample examples repository](https://github.com/n1k0/casperjs/tree/master/samples).
18
+ Don't hesitate to pull request for any cool example of yours as well!
19
+
20
+ **Read the [full documentation](http://casperjs.org/) on casperjs dedicated website.**
21
+
22
+ Subscribe to the [project mailing-list](https://groups.google.com/forum/#!forum/casperjs)
23
+
24
+ Follow the CasperJS project [on twitter](https://twitter.com/casperjs_org) and [Google+](https://plus.google.com/b/106641872690063476159/).
25
+
26
+ ## Contributing to the docs
27
+
28
+ CasperJS's documentation is written using the [Markdown format](http://daringfireball.net/projects/markdown/), and hosted on Github thanks to the [Github Pages Feature](http://pages.github.com/).
29
+
30
+ To view the source files on github, head to [the gh-pages branch](https://github.com/n1k0/casperjs/tree/gh-pages), and check the [documentation's README](https://github.com/n1k0/casperjs/tree/gh-pages#readme) for further instructions.
@@ -0,0 +1,292 @@
1
+ /*!
2
+ * Casper is a navigation utility for PhantomJS.
3
+ *
4
+ * Documentation: http://casperjs.org/
5
+ * Repository: http://github.com/n1k0/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
+ /*global console phantom require*/
32
+
33
+ if (!phantom || phantom.version.major !== 1 || phantom.version.minor < 5) {
34
+ console.error('CasperJS needs at least PhantomJS v1.5.0');
35
+ phantom.exit(1);
36
+ }
37
+
38
+ (function bootstrap(global) {
39
+ "use strict";
40
+ /**
41
+ * Loads and initialize the CasperJS environment.
42
+ */
43
+ phantom.loadCasper = function loadCasper() {
44
+ // Patching fs
45
+ // TODO: watch for these methods being implemented in official fs module
46
+ var fs = (function _fs(fs) {
47
+ if (!fs.hasOwnProperty('basename')) {
48
+ fs.basename = function basename(path) {
49
+ return path.replace(/.*\//, '');
50
+ };
51
+ }
52
+ if (!fs.hasOwnProperty('dirname')) {
53
+ fs.dirname = function dirname(path) {
54
+ return path.replace(/\\/g, '/').replace(/\/[^\/]*$/, '');
55
+ };
56
+ }
57
+ if (!fs.hasOwnProperty('isWindows')) {
58
+ fs.isWindows = function isWindows() {
59
+ var testPath = arguments[0] || this.workingDirectory;
60
+ return (/^[a-z]{1,2}:/i).test(testPath) || testPath.indexOf("\\\\") === 0;
61
+ };
62
+ }
63
+ if (!fs.hasOwnProperty('pathJoin')) {
64
+ fs.pathJoin = function pathJoin() {
65
+ return Array.prototype.join.call(arguments, this.separator);
66
+ };
67
+ }
68
+ return fs;
69
+ })(require('fs'));
70
+
71
+ // casper root path
72
+ if (!phantom.casperPath) {
73
+ try {
74
+ phantom.casperPath = phantom.args.map(function _map(i) {
75
+ var match = i.match(/^--casper-path=(.*)/);
76
+ if (match) {
77
+ return fs.absolute(match[1]);
78
+ }
79
+ }).filter(function _filter(path) {
80
+ return fs.isDirectory(path);
81
+ }).pop();
82
+ } catch (e) {}
83
+ }
84
+
85
+ if (!phantom.casperPath) {
86
+ console.error("Couldn't find nor compute phantom.casperPath, exiting.");
87
+ phantom.exit(1);
88
+ }
89
+
90
+ // Embedded, up-to-date, validatable & controlable CoffeeScript
91
+ phantom.injectJs(fs.pathJoin(phantom.casperPath, 'modules', 'vendors', 'coffee-script.js'));
92
+
93
+ // custom global CasperError
94
+ global.CasperError = function CasperError(msg) {
95
+ 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
+ this.message = msg;
103
+ this.name = 'CasperError';
104
+ };
105
+
106
+ // standard Error prototype inheritance
107
+ global.CasperError.prototype = Object.getPrototypeOf(new Error());
108
+
109
+ // CasperJS version, extracted from package.json - see http://semver.org/
110
+ phantom.casperVersion = (function getVersion(path) {
111
+ var parts, patchPart, pkg, pkgFile;
112
+ var fs = require('fs');
113
+ pkgFile = fs.absolute(fs.pathJoin(path, 'package.json'));
114
+ if (!fs.exists(pkgFile)) {
115
+ throw new global.CasperError('Cannot find package.json at ' + pkgFile);
116
+ }
117
+ try {
118
+ pkg = JSON.parse(require('fs').read(pkgFile));
119
+ } catch (e) {
120
+ throw new global.CasperError('Cannot read package file contents: ' + e);
121
+ }
122
+ parts = pkg.version.trim().split(".");
123
+ if (parts < 3) {
124
+ throw new global.CasperError("Invalid version number");
125
+ }
126
+ patchPart = parts[2].split('-');
127
+ return {
128
+ major: ~~parts[0] || 0,
129
+ minor: ~~parts[1] || 0,
130
+ patch: ~~patchPart[0] || 0,
131
+ ident: patchPart[1] || "",
132
+ toString: function toString() {
133
+ var version = [this.major, this.minor, this.patch].join('.');
134
+ if (this.ident) {
135
+ version = [version, this.ident].join('-');
136
+ }
137
+ return version;
138
+ }
139
+ };
140
+ })(phantom.casperPath);
141
+
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;
233
+
234
+ // casper cli args
235
+ phantom.casperArgs = require('cli').parse(phantom.args);
236
+
237
+ // loaded status
238
+ phantom.casperLoaded = true;
239
+ };
240
+
241
+ /**
242
+ * Initializes the CasperJS Command Line Interface.
243
+ */
244
+ phantom.initCasperCli = function initCasperCli() {
245
+ var fs = require("fs");
246
+
247
+ if (!!phantom.casperArgs.options.version) {
248
+ console.log(phantom.casperVersion.toString());
249
+ phantom.exit(0);
250
+ } else if (phantom.casperArgs.get(0) === "test") {
251
+ phantom.casperScript = fs.absolute(fs.pathJoin(phantom.casperPath, 'tests', 'run.js'));
252
+ phantom.casperArgs.drop("test");
253
+ } else if (phantom.casperArgs.args.length === 0 || !!phantom.casperArgs.options.help) {
254
+ var phantomVersion = [phantom.version.major, phantom.version.minor, phantom.version.patch].join('.');
255
+ var f = require("utils").format;
256
+ console.log(f('CasperJS version %s at %s, using PhantomJS version %s',
257
+ phantom.casperVersion.toString(),
258
+ phantom.casperPath, phantomVersion));
259
+ console.log(fs.read(fs.pathJoin(phantom.casperPath, 'bin', 'usage.txt')));
260
+ phantom.exit(0);
261
+ }
262
+
263
+
264
+ if (!phantom.casperScript) {
265
+ phantom.casperScript = phantom.casperArgs.get(0);
266
+ }
267
+
268
+ if (!fs.isFile(phantom.casperScript)) {
269
+ console.error('Unable to open file: ' + phantom.casperScript);
270
+ phantom.exit(1);
271
+ }
272
+
273
+ // filter out the called script name from casper args
274
+ phantom.casperArgs.drop(phantom.casperScript);
275
+
276
+ // passed casperjs script execution
277
+ phantom.injectJs(phantom.casperScript);
278
+ };
279
+
280
+ if (!phantom.casperLoaded) {
281
+ try {
282
+ phantom.loadCasper();
283
+ } catch (e) {
284
+ console.error("Unable to load casper environment: " + e);
285
+ phantom.exit();
286
+ }
287
+ }
288
+
289
+ if (true === phantom.casperArgs.get('cli')) {
290
+ phantom.initCasperCli();
291
+ }
292
+ })(window);