casperjs 1.0.0.RC1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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);