bauxite 0.6.18 → 0.6.19

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 (205) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +21 -21
  3. data/README.md +293 -293
  4. data/Rakefile +128 -128
  5. data/bin/bauxite +27 -27
  6. data/doc/Bauxite.html +6 -9
  7. data/doc/Bauxite/Action.html +298 -315
  8. data/doc/Bauxite/ActionModule.html +23 -26
  9. data/doc/Bauxite/Application.html +36 -38
  10. data/doc/Bauxite/Context.html +303 -303
  11. data/doc/Bauxite/Errors.html +6 -9
  12. data/doc/Bauxite/Errors/AssertionError.html +6 -9
  13. data/doc/Bauxite/Errors/FileNotFoundError.html +6 -9
  14. data/doc/Bauxite/Errors/FormatError.html +6 -9
  15. data/doc/Bauxite/Loggers.html +6 -9
  16. data/doc/Bauxite/Loggers/CompositeLogger.html +29 -32
  17. data/doc/Bauxite/Loggers/EchoLogger.html +10 -13
  18. data/doc/Bauxite/Loggers/FileLogger.html +25 -28
  19. data/doc/Bauxite/Loggers/HtmlLogger.html +99 -102
  20. data/doc/Bauxite/Loggers/NullLogger.html +16 -19
  21. data/doc/Bauxite/Loggers/ReportLogger.html +43 -46
  22. data/doc/Bauxite/Loggers/TerminalLogger.html +76 -79
  23. data/doc/Bauxite/Loggers/XtermLogger.html +28 -31
  24. data/doc/Bauxite/Parser.html +87 -89
  25. data/doc/Bauxite/ParserModule.html +19 -22
  26. data/doc/Bauxite/Selector.html +99 -105
  27. data/doc/Bauxite/SelectorModule.html +27 -30
  28. data/doc/README_md.html +117 -103
  29. data/doc/created.rid +58 -58
  30. data/doc/fonts.css +167 -167
  31. data/doc/fonts/Lato-Light.ttf +0 -0
  32. data/doc/fonts/Lato-LightItalic.ttf +0 -0
  33. data/doc/fonts/Lato-Regular.ttf +0 -0
  34. data/doc/fonts/Lato-RegularItalic.ttf +0 -0
  35. data/doc/fonts/SourceCodePro-Bold.ttf +0 -0
  36. data/doc/fonts/SourceCodePro-Regular.ttf +0 -0
  37. data/doc/images/add.png +0 -0
  38. data/doc/images/arrow_up.png +0 -0
  39. data/doc/images/brick.png +0 -0
  40. data/doc/images/brick_link.png +0 -0
  41. data/doc/images/bug.png +0 -0
  42. data/doc/images/bullet_black.png +0 -0
  43. data/doc/images/bullet_toggle_minus.png +0 -0
  44. data/doc/images/bullet_toggle_plus.png +0 -0
  45. data/doc/images/date.png +0 -0
  46. data/doc/images/delete.png +0 -0
  47. data/doc/images/find.png +0 -0
  48. data/doc/images/loadingAnimation.gif +0 -0
  49. data/doc/images/macFFBgHack.png +0 -0
  50. data/doc/images/package.png +0 -0
  51. data/doc/images/page_green.png +0 -0
  52. data/doc/images/page_white_text.png +0 -0
  53. data/doc/images/page_white_width.png +0 -0
  54. data/doc/images/plugin.png +0 -0
  55. data/doc/images/ruby.png +0 -0
  56. data/doc/images/tag_blue.png +0 -0
  57. data/doc/images/tag_green.png +0 -0
  58. data/doc/images/transparent.png +0 -0
  59. data/doc/images/wrench.png +0 -0
  60. data/doc/images/wrench_orange.png +0 -0
  61. data/doc/images/zoom.png +0 -0
  62. data/doc/index.html +117 -103
  63. data/doc/js/darkfish.js +32 -11
  64. data/doc/js/jquery.js +0 -0
  65. data/doc/js/navigation.js +0 -0
  66. data/doc/js/search.js +0 -0
  67. data/doc/js/search_index.js +1 -1
  68. data/doc/js/searcher.js +0 -0
  69. data/doc/rdoc.css +580 -580
  70. data/doc/table_of_contents.html +69 -72
  71. data/lib/bauxite.rb +28 -28
  72. data/lib/bauxite/actions/alias.rb +51 -51
  73. data/lib/bauxite/actions/assert.rb +49 -49
  74. data/lib/bauxite/actions/asserth.rb +60 -60
  75. data/lib/bauxite/actions/assertm.rb +49 -49
  76. data/lib/bauxite/actions/assertv.rb +40 -40
  77. data/lib/bauxite/actions/assertw.rb +47 -47
  78. data/lib/bauxite/actions/break.rb +39 -39
  79. data/lib/bauxite/actions/capture.rb +61 -61
  80. data/lib/bauxite/actions/click.rb +36 -36
  81. data/lib/bauxite/actions/debug.rb +103 -103
  82. data/lib/bauxite/actions/doif.rb +43 -43
  83. data/lib/bauxite/actions/dounless.rb +43 -43
  84. data/lib/bauxite/actions/echo.rb +36 -36
  85. data/lib/bauxite/actions/exec.rb +46 -46
  86. data/lib/bauxite/actions/exit.rb +35 -35
  87. data/lib/bauxite/actions/failif.rb +52 -52
  88. data/lib/bauxite/actions/js.rb +41 -41
  89. data/lib/bauxite/actions/load.rb +49 -49
  90. data/lib/bauxite/actions/open.rb +35 -35
  91. data/lib/bauxite/actions/params.rb +40 -40
  92. data/lib/bauxite/actions/replace.rb +37 -37
  93. data/lib/bauxite/actions/reset.rb +38 -38
  94. data/lib/bauxite/actions/return.rb +68 -68
  95. data/lib/bauxite/actions/ruby.rb +58 -58
  96. data/lib/bauxite/actions/select.rb +48 -48
  97. data/lib/bauxite/actions/set.rb +39 -39
  98. data/lib/bauxite/actions/setif.rb +44 -44
  99. data/lib/bauxite/actions/source.rb +44 -44
  100. data/lib/bauxite/actions/store.rb +38 -38
  101. data/lib/bauxite/actions/submit.rb +37 -37
  102. data/lib/bauxite/actions/test.rb +67 -67
  103. data/lib/bauxite/actions/tryload.rb +71 -71
  104. data/lib/bauxite/actions/wait.rb +38 -38
  105. data/lib/bauxite/actions/write.rb +44 -44
  106. data/lib/bauxite/application.rb +349 -349
  107. data/lib/bauxite/core/action.rb +199 -199
  108. data/lib/bauxite/core/context.rb +791 -791
  109. data/lib/bauxite/core/errors.rb +41 -41
  110. data/lib/bauxite/core/logger.rb +169 -169
  111. data/lib/bauxite/core/parser.rb +85 -85
  112. data/lib/bauxite/core/selector.rb +152 -152
  113. data/lib/bauxite/loggers/composite.rb +91 -91
  114. data/lib/bauxite/loggers/echo.rb +36 -36
  115. data/lib/bauxite/loggers/file.rb +68 -68
  116. data/lib/bauxite/loggers/html.rb +154 -154
  117. data/lib/bauxite/loggers/terminal.rb +134 -134
  118. data/lib/bauxite/loggers/xterm.rb +101 -101
  119. data/lib/bauxite/parsers/csv.rb +43 -43
  120. data/lib/bauxite/parsers/default.rb +42 -42
  121. data/lib/bauxite/parsers/html.rb +79 -79
  122. data/lib/bauxite/selectors/attr.rb +39 -39
  123. data/lib/bauxite/selectors/frame.rb +60 -60
  124. data/lib/bauxite/selectors/json.rb +88 -88
  125. data/lib/bauxite/selectors/sid.rb +38 -38
  126. data/lib/bauxite/selectors/smart.rb +80 -80
  127. data/lib/bauxite/selectors/window.rb +77 -77
  128. data/test/alert.bxt +3 -3
  129. data/test/alert/page.html +4 -4
  130. data/test/alias.bxt +9 -9
  131. data/test/asserth.bxt +2 -2
  132. data/test/assertv.bxt +1 -1
  133. data/test/assertw.bxt +7 -7
  134. data/test/broken.bxt.manual +0 -0
  135. data/test/bug_load_path.bxt.manual +0 -0
  136. data/test/bug_load_path/broken.bxt.manual +0 -0
  137. data/test/bug_load_path/test.bxt +0 -0
  138. data/test/capture.bxt.manual +20 -20
  139. data/test/capture/my_test.bxt +1 -1
  140. data/test/capture/page.html +6 -6
  141. data/test/capture_on_error.bxt.manual +3 -3
  142. data/test/capture_on_error/my_test.bxt +1 -1
  143. data/test/capture_on_error/page.html +2 -2
  144. data/test/debug.bxt.manual +0 -0
  145. data/test/default_selector.bxt.manual +7 -7
  146. data/test/default_selector/page.html +10 -10
  147. data/test/default_selector_var.bxt +1 -1
  148. data/test/delay.bxt +2 -2
  149. data/test/delay/page.html +4 -4
  150. data/test/doif.bxt +6 -6
  151. data/test/dounless.bxt +6 -6
  152. data/test/exec.bxt +6 -6
  153. data/test/exit.bxt +3 -3
  154. data/test/exit/test.bxt +3 -3
  155. data/test/extension.bxt.manual +4 -4
  156. data/test/extension/custom.rb +12 -12
  157. data/test/extension/page.html +4 -4
  158. data/test/failif.bxt +7 -7
  159. data/test/failif/page.html +5 -5
  160. data/test/format.bxt +17 -17
  161. data/test/format/page.html +6 -6
  162. data/test/frame.bxt +6 -6
  163. data/test/frame/child_frame.html +6 -6
  164. data/test/frame/grandchild_frame.html +4 -4
  165. data/test/frame/page.html +4 -4
  166. data/test/js.bxt +4 -4
  167. data/test/json.bxt +19 -19
  168. data/test/json/array.json +3 -3
  169. data/test/json/object.json +13 -13
  170. data/test/load.bxt +18 -18
  171. data/test/load/child.bxt +12 -12
  172. data/test/parsers.bxt +1 -1
  173. data/test/parsers.csv +7 -7
  174. data/test/parsers.html +32 -32
  175. data/test/parsers/page.html +6 -6
  176. data/test/return.bxt +1 -1
  177. data/test/return/f1.bxt +1 -1
  178. data/test/return/f2.bxt +1 -1
  179. data/test/return/f3.bxt +1 -1
  180. data/test/return/f4.bxt +2 -2
  181. data/test/ruby.bxt +1 -1
  182. data/test/ruby/custom.rb +5 -5
  183. data/test/select.bxt +9 -9
  184. data/test/select/page.html +8 -8
  185. data/test/selectors.bxt +7 -7
  186. data/test/selectors/page.html +6 -6
  187. data/test/set_builtin.bxt +5 -0
  188. data/test/set_builtin/page.html +5 -0
  189. data/test/setif.bxt +3 -3
  190. data/test/smart_selector.bxt +17 -17
  191. data/test/smart_selector/page.html +17 -17
  192. data/test/stdin.bxt +0 -0
  193. data/test/submit.bxt +4 -4
  194. data/test/submit/page.html +6 -6
  195. data/test/submit/page2.html +4 -4
  196. data/test/test.bxt.manual +6 -6
  197. data/test/test/test1.bxt +2 -2
  198. data/test/test/test2.bxt +3 -3
  199. data/test/test/test3.bxt +2 -2
  200. data/test/test/test4.bxt +1 -1
  201. data/test/test/test5.bxt +1 -1
  202. data/test/window.bxt +14 -14
  203. data/test/window/page.html +5 -5
  204. data/test/window/popup.html +4 -4
  205. metadata +5 -3
@@ -1,38 +1,38 @@
1
- #--
2
- # Copyright (c) 2014 Patricio Zavolinsky
3
- #
4
- # Permission is hereby granted, free of charge, to any person obtaining a copy
5
- # of this software and associated documentation files (the "Software"), to deal
6
- # in the Software without restriction, including without limitation the rights
7
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
- # copies of the Software, and to permit persons to whom the Software is
9
- # furnished to do so, subject to the following conditions:
10
- #
11
- # The above copyright notice and this permission notice shall be included in
12
- # all copies or substantial portions of the Software.
13
- #
14
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
- # SOFTWARE.
21
- #++
22
-
23
- class Bauxite::Action
24
- # Wait for the specified number of +seconds+.
25
- #
26
- # For example:
27
- # wait 5
28
- # # => this would wait for 5 seconds and then continue
29
- #
30
- # :category: Action Methods
31
- def wait(seconds)
32
- seconds = seconds.to_i
33
- seconds.times do |i|
34
- @ctx.logger.progress(seconds-i)
35
- sleep(1.0)
36
- end
37
- end
38
- end
1
+ #--
2
+ # Copyright (c) 2014 Patricio Zavolinsky
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ # of this software and associated documentation files (the "Software"), to deal
6
+ # in the Software without restriction, including without limitation the rights
7
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ # copies of the Software, and to permit persons to whom the Software is
9
+ # furnished to do so, subject to the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be included in
12
+ # all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
+ # SOFTWARE.
21
+ #++
22
+
23
+ class Bauxite::Action
24
+ # Wait for the specified number of +seconds+.
25
+ #
26
+ # For example:
27
+ # wait 5
28
+ # # => this would wait for 5 seconds and then continue
29
+ #
30
+ # :category: Action Methods
31
+ def wait(seconds)
32
+ seconds = seconds.to_i
33
+ seconds.times do |i|
34
+ @ctx.logger.progress(seconds-i)
35
+ sleep(1.0)
36
+ end
37
+ end
38
+ end
@@ -1,44 +1,44 @@
1
- #--
2
- # Copyright (c) 2014 Patricio Zavolinsky
3
- #
4
- # Permission is hereby granted, free of charge, to any person obtaining a copy
5
- # of this software and associated documentation files (the "Software"), to deal
6
- # in the Software without restriction, including without limitation the rights
7
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
- # copies of the Software, and to permit persons to whom the Software is
9
- # furnished to do so, subject to the following conditions:
10
- #
11
- # The above copyright notice and this permission notice shall be included in
12
- # all copies or substantial portions of the Software.
13
- #
14
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
- # SOFTWARE.
21
- #++
22
-
23
- class Bauxite::Action
24
- # Sets the value of the selected element to +text+.
25
- #
26
- # +text+ is subject to variable expansion (see Context#expand).
27
- #
28
- # For example:
29
- # # assuming <input type="text" name="username" />
30
- # write name=username "John"
31
- # # => this would type the word 'John' in the username textbox
32
- #
33
- # :category: Action Methods
34
- def write(selector, text)
35
- @ctx.find(selector) do |e|
36
- begin
37
- e.clear
38
- rescue Selenium::WebDriver::Error::UnknownError # user-editable...
39
- # do nothing (if this should fail, it will in the line below)
40
- end
41
- e.send_keys(text)
42
- end
43
- end
44
- end
1
+ #--
2
+ # Copyright (c) 2014 Patricio Zavolinsky
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ # of this software and associated documentation files (the "Software"), to deal
6
+ # in the Software without restriction, including without limitation the rights
7
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ # copies of the Software, and to permit persons to whom the Software is
9
+ # furnished to do so, subject to the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be included in
12
+ # all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
+ # SOFTWARE.
21
+ #++
22
+
23
+ class Bauxite::Action
24
+ # Sets the value of the selected element to +text+.
25
+ #
26
+ # +text+ is subject to variable expansion (see Context#expand).
27
+ #
28
+ # For example:
29
+ # # assuming <input type="text" name="username" />
30
+ # write name=username "John"
31
+ # # => this would type the word 'John' in the username textbox
32
+ #
33
+ # :category: Action Methods
34
+ def write(selector, text)
35
+ @ctx.find(selector) do |e|
36
+ begin
37
+ e.clear
38
+ rescue Selenium::WebDriver::Error::UnknownError # user-editable...
39
+ # do nothing (if this should fail, it will in the line below)
40
+ end
41
+ e.send_keys(text)
42
+ end
43
+ end
44
+ end
@@ -1,350 +1,350 @@
1
- #--
2
- # Copyright (c) 2014 Patricio Zavolinsky
3
- #
4
- # Permission is hereby granted, free of charge, to any person obtaining a copy
5
- # of this software and associated documentation files (the "Software"), to deal
6
- # in the Software without restriction, including without limitation the rights
7
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
- # copies of the Software, and to permit persons to whom the Software is
9
- # furnished to do so, subject to the following conditions:
10
- #
11
- # The above copyright notice and this permission notice shall be included in
12
- # all copies or substantial portions of the Software.
13
- #
14
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
- # SOFTWARE.
21
- #++
22
-
23
- require 'optparse'
24
- require_relative 'core/context'
25
-
26
- module Bauxite
27
- # +bauxite+ command-line program.
28
- #
29
- # This program executes Bauxite tests and outputs the execution progress
30
- # and tests results to the terminal.
31
- #
32
- # == Synopsis
33
- #
34
- # bauxite [OPTIONS] file1 file2 ...
35
- # # => Executes file1, then file2, and so on.
36
- #
37
- # bauxite [OPTIONS] -d
38
- # # => Start Bauxite directly in the debug console.
39
- #
40
- # bauxite [OPTIONS]
41
- # # => Start Bauxite and read test actions from the standard input.
42
- #
43
- # == Options
44
- # For a detailed list of options for your Bauxite version execute:
45
- # bauxite -h
46
- #
47
- #
48
- # [-v, \--verbose]
49
- # Show verbose error messages (i.e. print exception names and
50
- # backtraces).
51
- #
52
- # [-t, \--timeout SECONDS]
53
- # Number of seconds to wait before issuing a timeout error. This
54
- # timeout applies only to Selectors.
55
- #
56
- # [-o, \--open_timeout SECONDS]
57
- # Number of seconds to wait before issuing a timeout error. This
58
- # timeout applies only to page loading times (i.e. Net::HTTP).
59
- #
60
- # [-d, \--debug]
61
- # If an error occurs, break into the debug console. This mode is very
62
- # useful to try different selector combinations and debug
63
- # NoSuchElementError errors.
64
- #
65
- # [-p, \--provider DRIVER]
66
- # Selenium WebDriver provider. Defaults to +firefox+.
67
- #
68
- # Other options include:
69
- # - +remote+
70
- # - +ie+
71
- # - +chrome+
72
- # - +android+
73
- # - +iphone+
74
- # - +opera+
75
- # - +phantomjs+
76
- # - +safari+
77
- #
78
- # Driver availability dependes on the system running Bauxite.
79
- # [-P, \--provider-option OPTION]
80
- # A <tt>name=value</tt> pair of options that are directly forwarded to
81
- # the Selenium WebDriver provider. This option argument can appear
82
- # multiple times in the command line to specify multiple options.
83
- #
84
- # [-l, \--logger LOGGER]
85
- # Logger instance to use. Defaults to +xterm+ if the +TERM+ environment
86
- # variable is set to +xterm+, otherwise it defaults to +terminal+.
87
- #
88
- # To see a complete list of the available loggers execute:
89
- # bauxite -h
90
- #
91
- # Note that multiple instances of this option can be specified.
92
- #
93
- # [-L, \--logger-option OPTION]
94
- # A <tt>name=value</tt> pair of options that are directly forwarded to
95
- # the logger. This option argument can appear multiple times in the
96
- # command line to specify multiple options.
97
- #
98
- # [-r, \--reset]
99
- # Issue a Action#reset action between every test specified in
100
- # the command line. This option enforces test isolation by resetting
101
- # the test context before each test (this removes cookies, sessions,
102
- # etc. from the previous test).
103
- #
104
- # [-w, \--wait]
105
- # Wait for user input when the test completes instead of closing the
106
- # browser window.
107
- #
108
- # [-s, \--selector SELECTOR]
109
- # Default selector strategy. This strategy is applied if the selector
110
- # text does not contain an <tt>=</tt> sign.
111
- #
112
- # To see a complete list of the available selectors execute:
113
- # bauxite -h
114
- #
115
- # [-c, \--capture]
116
- # If the test fails, capture a screenshot in the +output+ directory.
117
- # See the \--output option below.
118
- #
119
- # [\--csv-summary FILE]
120
- # Output a single-line CSV summary ideal to feed into the Plot Jenkins
121
- # plugin. If +FILE+ is not specified, defaults to +summary.csv+
122
- #
123
- # [\--output DIR]
124
- # Output directory for generated artifacts. Defaults to the current
125
- # working directory.
126
- #
127
- # [-u, \--url URL]
128
- # This option is an alias of:
129
- # -p remote -P url=URL
130
- # If +URL+ is not present <tt>http://localhost:4444/wd/hub</tt> will be
131
- # assumed.
132
- #
133
- # [\--jenkins DIR]
134
- # Configures default options for Jenkins integration. This option is an
135
- # alias of:
136
- # -p remote -P url=http://localhost:4444/wd/hub -l echo -l html
137
- # -L html_package=true -c --csv-summary
138
- # --output DIR
139
- # Note that any of the options above can be overridden by specifying the
140
- # option after the <tt>--jenkins</tt> option. For example:
141
- # --jenkins -u selenium.my-organization.com:4445
142
- #
143
- # [-e, \--extension DIR]
144
- # Loads every Ruby file (*.rb) inside +DIR+ (and subdirectories). This
145
- # option can be used to load custom Bauxite extensions (e.g. Actions,
146
- # Selectors, Loggers, etc.) for a specific test run.
147
- #
148
- # For example:
149
- # # === custom/my_selector.rb ======= #
150
- # class Bauxite::Selector
151
- # def by_attr(value)
152
- # attr "by_attr:#{value}"
153
- # end
154
- # end
155
- # # === end custom/my_selector.rb === #
156
- #
157
- # # === custom/my_test.bxt ========== #
158
- # # ...
159
- # assert "by_attr=attr_value" hello
160
- # # ...
161
- # # === end custom/my_test.bxt ====== #
162
- #
163
- # bauxite -e custom custom/my_test.bxt
164
- #
165
- # [\--version]
166
- # Shows the Bauxite version.
167
- #
168
- # == Exit Status
169
- # The +bauxite+ program exits with +zero+ if every action in the test
170
- # succeeded and +non-zero+ otherwise.
171
- #
172
- # If the test run includes multiple Action#test actions, the exit status
173
- # equals the number of failed test cases (again, +zero+ indicates success).
174
- #
175
- class Application
176
- def self.start #:nodoc:
177
- options = {
178
- :logger => [],
179
- :verbose => false,
180
- :break => false,
181
- :driver => 'firefox',
182
- :debug => false,
183
- :timeout => 10,
184
- :open_timeout => 60,
185
- :reset => false,
186
- :selector => 'sid',
187
- :driver_opt => {},
188
- :logger_opt => {},
189
- :extensions => []
190
- }
191
-
192
- default_logger = (ENV['TERM'] == 'xterm') ? 'xterm' : 'terminal'
193
-
194
- OptionParser.new do |opts|
195
- opts.banner = "Usage: bauxite [options] [files...]"
196
-
197
- def opts.o=(o)
198
- @o = o
199
- end
200
- def opts.single(*args)
201
- on(*args[1..-1]) do |v|
202
- @o[args[0]] = v
203
- end
204
- self
205
- end
206
- def opts.hash(*args)
207
- on(*args[1..-1]) do |v|
208
- n,v = v.split('=', 2)
209
- @o[args[0]][n.to_sym] = v || true
210
- end
211
- self
212
- end
213
- def opts.multi(*args)
214
- on(*args[1..-1]) do |v|
215
- @o[args[0]] << v
216
- end
217
- self
218
- end
219
- opts.o = options
220
-
221
- opts.separator ""
222
- opts.separator "Options: "
223
- opts
224
- .single(:verbose , "-v", "--verbose", "Show verbose errors")
225
- .single(:timeout , "-t", "--timeout SECONDS", "Selector timeout (#{options[:timeout]}s)")
226
- .single(:open_timeout, "-o", "--open-timeout SECONDS", "Open timeout (#{options[:open_timeout]}s)")
227
- .single(:debug , "-d", "--debug", "Break to debug on error. "+
228
- "Start the debug console if no input files given.")
229
- .single(:driver , "-p", "--provider PROVIDER" , "Driver provider")
230
- .hash( :driver_opt , "-P", "--provider-option OPTION", "Provider options (name=value)")
231
- .multi( :logger , "-l", "--logger LOGGER" , "Logger type ('#{default_logger}')")
232
- .hash( :logger_opt , "-L", "--logger-option OPTION" , "Logger options (name=value)")
233
- .single(:reset , "-r", "--reset" , "Reset driver between tests")
234
- .single(:wait , "-w", "--wait" , "Wait for ENTER before exiting")
235
- .single(:selector , "-s", "--selector SELECTOR" , "Default selector ('#{options[:selector]}')")
236
- .single(:capture , "-c", "--capture" , "If the test fails, capture a screenshot")
237
- .single(:output , "--output DIR" , "Output directory for generated artifacts")
238
- .multi( :extensions , "-e", "--extension DIR" , "Load extensions from DIR")
239
-
240
- opts.on("-u", "--url [URL]", "Configure the remote provider listening in the given url") do |v|
241
- v = 'localhost:4444' unless v
242
- v = 'http://'+v unless v.match /^https?:\/\//
243
- v = v + '/wd/hub' unless v.end_with? '/wd/hub'
244
- options[:driver] = 'remote'
245
- options[:driver_opt][:url] = v
246
- end
247
-
248
- opts.on("--csv-summary [FILE]", "Output a single-line CSV summary") { |v| options[:csv] = v || 'summary.csv' }
249
-
250
- opts.on("--jenkins DIR", "Configure default options for Jenkins integration") do |v|
251
- options[:driver] = 'remote'
252
- options[:driver_opt][:url] = 'http://localhost:4444/wd/hub'
253
- options[:logger] = ['echo', 'html']
254
- options[:output] = v
255
- options[:logger_opt][:html_package] = true
256
- options[:capture] = true
257
- options[:csv] = 'summary.csv'
258
- end
259
-
260
- opts.on("--version", "Show version") do
261
- puts "bauxite #{Bauxite::VERSION}"
262
- exit
263
- end
264
-
265
- opts.separator ""
266
- opts.separator "Loggers:"
267
- Context::loggers.sort.each do |s|
268
- opts.separator " #{s}"
269
- end
270
-
271
- opts.separator ""
272
- opts.separator "Selectors:".ljust(32)+" Actions:"
273
- max_action_size = Context::max_action_name_size
274
- selectors = Context::selectors.sort
275
- actions = Context::actions.sort
276
- [selectors.size, actions.size].max.times.zip(selectors, actions).each do |idx,s,a|
277
- a = a ? "#{a.ljust(max_action_size)} #{Context.action_args(a).join(' ')}" : ''
278
- s = '' unless s
279
- opts.separator " #{s.ljust(28)} #{a}"
280
- end
281
-
282
- opts.separator ""
283
- end.parse!
284
-
285
- options[:logger] << default_logger unless options[:logger].size > 0
286
-
287
- ctx = nil
288
- begin
289
- ctx = Context.new(options)
290
- rescue StandardError => e
291
- puts e.message
292
- if options[:verbose]
293
- p e
294
- puts e.backtrace
295
- end
296
- exit false
297
- end
298
-
299
- files = ARGV
300
- files = ['stdin'] if files.size == 0 and not options[:debug]
301
-
302
- actions = files.map { |f| "load \"#{f.gsub('"', '""')}\"" }
303
-
304
- if options[:reset] and files.size > 1
305
- actions = actions.map { |a| [a] }.inject do |sum,a|
306
- sum += ['reset']
307
- sum + a
308
- end.flatten
309
- end
310
-
311
- if options[:debug] and actions.size == 0
312
- actions = ['debug']
313
- end
314
-
315
- begin
316
- ctx.start(actions)
317
- rescue StandardError => e
318
- exit false
319
- ensure
320
- if ctx.tests.any?
321
-
322
- if (csv_file = options[:csv])
323
- total = ctx.tests.size
324
- ok = ctx.tests.inject(0) { |s,t| s + (t[:status] == 'OK' ? 1 : 0) }
325
- failed = total - ok
326
- time = ctx.tests.inject(0) { |s,t| s + t[:time] }
327
- File.open(ctx.output_path(csv_file), 'w') do |f|
328
- f.write "Total,OK,Failed,Time\n#{total},#{ok},#{failed},#{time}\n"
329
- end
330
- end
331
-
332
- failed = 0
333
-
334
- puts
335
- puts 'Test summary:'
336
- puts '============='
337
- puts 'Name'.ljust(40 ) + ' Time'.ljust(7 ) + ' Status'.ljust(7)+' Error'
338
- puts ''.ljust(40, '-') + ' '.ljust(7, '-') + ' '.ljust(7, '-' )+' '.ljust(5, '-')
339
- ctx.tests.each do |t|
340
- error = t[:error]
341
- error = error ? error.message : ''
342
- puts t[:name].ljust(40) + ' ' + t[:time].round(2).to_s.rjust(6) + ' ' + t[:status].ljust(6) + ' ' + error
343
- failed += 1 if t[:status] != 'OK'
344
- end
345
- exit failed if failed > 0
346
- end
347
- end
348
- end
349
- end
1
+ #--
2
+ # Copyright (c) 2014 Patricio Zavolinsky
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ # of this software and associated documentation files (the "Software"), to deal
6
+ # in the Software without restriction, including without limitation the rights
7
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ # copies of the Software, and to permit persons to whom the Software is
9
+ # furnished to do so, subject to the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be included in
12
+ # all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
+ # SOFTWARE.
21
+ #++
22
+
23
+ require 'optparse'
24
+ require_relative 'core/context'
25
+
26
+ module Bauxite
27
+ # +bauxite+ command-line program.
28
+ #
29
+ # This program executes Bauxite tests and outputs the execution progress
30
+ # and tests results to the terminal.
31
+ #
32
+ # == Synopsis
33
+ #
34
+ # bauxite [OPTIONS] file1 file2 ...
35
+ # # => Executes file1, then file2, and so on.
36
+ #
37
+ # bauxite [OPTIONS] -d
38
+ # # => Start Bauxite directly in the debug console.
39
+ #
40
+ # bauxite [OPTIONS]
41
+ # # => Start Bauxite and read test actions from the standard input.
42
+ #
43
+ # == Options
44
+ # For a detailed list of options for your Bauxite version execute:
45
+ # bauxite -h
46
+ #
47
+ #
48
+ # [-v, \--verbose]
49
+ # Show verbose error messages (i.e. print exception names and
50
+ # backtraces).
51
+ #
52
+ # [-t, \--timeout SECONDS]
53
+ # Number of seconds to wait before issuing a timeout error. This
54
+ # timeout applies only to Selectors.
55
+ #
56
+ # [-o, \--open_timeout SECONDS]
57
+ # Number of seconds to wait before issuing a timeout error. This
58
+ # timeout applies only to page loading times (i.e. Net::HTTP).
59
+ #
60
+ # [-d, \--debug]
61
+ # If an error occurs, break into the debug console. This mode is very
62
+ # useful to try different selector combinations and debug
63
+ # NoSuchElementError errors.
64
+ #
65
+ # [-p, \--provider DRIVER]
66
+ # Selenium WebDriver provider. Defaults to +firefox+.
67
+ #
68
+ # Other options include:
69
+ # - +remote+
70
+ # - +ie+
71
+ # - +chrome+
72
+ # - +android+
73
+ # - +iphone+
74
+ # - +opera+
75
+ # - +phantomjs+
76
+ # - +safari+
77
+ #
78
+ # Driver availability dependes on the system running Bauxite.
79
+ # [-P, \--provider-option OPTION]
80
+ # A <tt>name=value</tt> pair of options that are directly forwarded to
81
+ # the Selenium WebDriver provider. This option argument can appear
82
+ # multiple times in the command line to specify multiple options.
83
+ #
84
+ # [-l, \--logger LOGGER]
85
+ # Logger instance to use. Defaults to +xterm+ if the +TERM+ environment
86
+ # variable is set to +xterm+, otherwise it defaults to +terminal+.
87
+ #
88
+ # To see a complete list of the available loggers execute:
89
+ # bauxite -h
90
+ #
91
+ # Note that multiple instances of this option can be specified.
92
+ #
93
+ # [-L, \--logger-option OPTION]
94
+ # A <tt>name=value</tt> pair of options that are directly forwarded to
95
+ # the logger. This option argument can appear multiple times in the
96
+ # command line to specify multiple options.
97
+ #
98
+ # [-r, \--reset]
99
+ # Issue a Action#reset action between every test specified in
100
+ # the command line. This option enforces test isolation by resetting
101
+ # the test context before each test (this removes cookies, sessions,
102
+ # etc. from the previous test).
103
+ #
104
+ # [-w, \--wait]
105
+ # Wait for user input when the test completes instead of closing the
106
+ # browser window.
107
+ #
108
+ # [-s, \--selector SELECTOR]
109
+ # Default selector strategy. This strategy is applied if the selector
110
+ # text does not contain an <tt>=</tt> sign.
111
+ #
112
+ # To see a complete list of the available selectors execute:
113
+ # bauxite -h
114
+ #
115
+ # [-c, \--capture]
116
+ # If the test fails, capture a screenshot in the +output+ directory.
117
+ # See the \--output option below.
118
+ #
119
+ # [\--csv-summary FILE]
120
+ # Output a single-line CSV summary ideal to feed into the Plot Jenkins
121
+ # plugin. If +FILE+ is not specified, defaults to +summary.csv+
122
+ #
123
+ # [\--output DIR]
124
+ # Output directory for generated artifacts. Defaults to the current
125
+ # working directory.
126
+ #
127
+ # [-u, \--url URL]
128
+ # This option is an alias of:
129
+ # -p remote -P url=URL
130
+ # If +URL+ is not present <tt>http://localhost:4444/wd/hub</tt> will be
131
+ # assumed.
132
+ #
133
+ # [\--jenkins DIR]
134
+ # Configures default options for Jenkins integration. This option is an
135
+ # alias of:
136
+ # -p remote -P url=http://localhost:4444/wd/hub -l echo -l html
137
+ # -L html_package=true -c --csv-summary
138
+ # --output DIR
139
+ # Note that any of the options above can be overridden by specifying the
140
+ # option after the <tt>--jenkins</tt> option. For example:
141
+ # --jenkins -u selenium.my-organization.com:4445
142
+ #
143
+ # [-e, \--extension DIR]
144
+ # Loads every Ruby file (*.rb) inside +DIR+ (and subdirectories). This
145
+ # option can be used to load custom Bauxite extensions (e.g. Actions,
146
+ # Selectors, Loggers, etc.) for a specific test run.
147
+ #
148
+ # For example:
149
+ # # === custom/my_selector.rb ======= #
150
+ # class Bauxite::Selector
151
+ # def by_attr(value)
152
+ # attr "by_attr:#{value}"
153
+ # end
154
+ # end
155
+ # # === end custom/my_selector.rb === #
156
+ #
157
+ # # === custom/my_test.bxt ========== #
158
+ # # ...
159
+ # assert "by_attr=attr_value" hello
160
+ # # ...
161
+ # # === end custom/my_test.bxt ====== #
162
+ #
163
+ # bauxite -e custom custom/my_test.bxt
164
+ #
165
+ # [\--version]
166
+ # Shows the Bauxite version.
167
+ #
168
+ # == Exit Status
169
+ # The +bauxite+ program exits with +zero+ if every action in the test
170
+ # succeeded and +non-zero+ otherwise.
171
+ #
172
+ # If the test run includes multiple Action#test actions, the exit status
173
+ # equals the number of failed test cases (again, +zero+ indicates success).
174
+ #
175
+ class Application
176
+ def self.start #:nodoc:
177
+ options = {
178
+ :logger => [],
179
+ :verbose => false,
180
+ :break => false,
181
+ :driver => 'firefox',
182
+ :debug => false,
183
+ :timeout => 10,
184
+ :open_timeout => 60,
185
+ :reset => false,
186
+ :selector => 'sid',
187
+ :driver_opt => {},
188
+ :logger_opt => {},
189
+ :extensions => []
190
+ }
191
+
192
+ default_logger = (ENV['TERM'] == 'xterm') ? 'xterm' : 'terminal'
193
+
194
+ OptionParser.new do |opts|
195
+ opts.banner = "Usage: bauxite [options] [files...]"
196
+
197
+ def opts.o=(o)
198
+ @o = o
199
+ end
200
+ def opts.single(*args)
201
+ on(*args[1..-1]) do |v|
202
+ @o[args[0]] = v
203
+ end
204
+ self
205
+ end
206
+ def opts.hash(*args)
207
+ on(*args[1..-1]) do |v|
208
+ n,v = v.split('=', 2)
209
+ @o[args[0]][n.to_sym] = v || true
210
+ end
211
+ self
212
+ end
213
+ def opts.multi(*args)
214
+ on(*args[1..-1]) do |v|
215
+ @o[args[0]] << v
216
+ end
217
+ self
218
+ end
219
+ opts.o = options
220
+
221
+ opts.separator ""
222
+ opts.separator "Options: "
223
+ opts
224
+ .single(:verbose , "-v", "--verbose", "Show verbose errors")
225
+ .single(:timeout , "-t", "--timeout SECONDS", "Selector timeout (#{options[:timeout]}s)")
226
+ .single(:open_timeout, "-o", "--open-timeout SECONDS", "Open timeout (#{options[:open_timeout]}s)")
227
+ .single(:debug , "-d", "--debug", "Break to debug on error. "+
228
+ "Start the debug console if no input files given.")
229
+ .single(:driver , "-p", "--provider PROVIDER" , "Driver provider")
230
+ .hash( :driver_opt , "-P", "--provider-option OPTION", "Provider options (name=value)")
231
+ .multi( :logger , "-l", "--logger LOGGER" , "Logger type ('#{default_logger}')")
232
+ .hash( :logger_opt , "-L", "--logger-option OPTION" , "Logger options (name=value)")
233
+ .single(:reset , "-r", "--reset" , "Reset driver between tests")
234
+ .single(:wait , "-w", "--wait" , "Wait for ENTER before exiting")
235
+ .single(:selector , "-s", "--selector SELECTOR" , "Default selector ('#{options[:selector]}')")
236
+ .single(:capture , "-c", "--capture" , "If the test fails, capture a screenshot")
237
+ .single(:output , "--output DIR" , "Output directory for generated artifacts")
238
+ .multi( :extensions , "-e", "--extension DIR" , "Load extensions from DIR")
239
+
240
+ opts.on("-u", "--url [URL]", "Configure the remote provider listening in the given url") do |v|
241
+ v = 'localhost:4444' unless v
242
+ v = 'http://'+v unless v.match /^https?:\/\//
243
+ v = v + '/wd/hub' unless v.end_with? '/wd/hub'
244
+ options[:driver] = 'remote'
245
+ options[:driver_opt][:url] = v
246
+ end
247
+
248
+ opts.on("--csv-summary [FILE]", "Output a single-line CSV summary") { |v| options[:csv] = v || 'summary.csv' }
249
+
250
+ opts.on("--jenkins DIR", "Configure default options for Jenkins integration") do |v|
251
+ options[:driver] = 'remote'
252
+ options[:driver_opt][:url] = 'http://localhost:4444/wd/hub'
253
+ options[:logger] = ['echo', 'html']
254
+ options[:output] = v
255
+ options[:logger_opt][:html_package] = true
256
+ options[:capture] = true
257
+ options[:csv] = 'summary.csv'
258
+ end
259
+
260
+ opts.on("--version", "Show version") do
261
+ puts "bauxite #{Bauxite::VERSION}"
262
+ exit
263
+ end
264
+
265
+ opts.separator ""
266
+ opts.separator "Loggers:"
267
+ Context::loggers.sort.each do |s|
268
+ opts.separator " #{s}"
269
+ end
270
+
271
+ opts.separator ""
272
+ opts.separator "Selectors:".ljust(32)+" Actions:"
273
+ max_action_size = Context::max_action_name_size
274
+ selectors = Context::selectors.sort
275
+ actions = Context::actions.sort
276
+ [selectors.size, actions.size].max.times.zip(selectors, actions).each do |idx,s,a|
277
+ a = a ? "#{a.ljust(max_action_size)} #{Context.action_args(a).join(' ')}" : ''
278
+ s = '' unless s
279
+ opts.separator " #{s.ljust(28)} #{a}"
280
+ end
281
+
282
+ opts.separator ""
283
+ end.parse!
284
+
285
+ options[:logger] << default_logger unless options[:logger].size > 0
286
+
287
+ ctx = nil
288
+ begin
289
+ ctx = Context.new(options)
290
+ rescue StandardError => e
291
+ puts e.message
292
+ if options[:verbose]
293
+ p e
294
+ puts e.backtrace
295
+ end
296
+ exit false
297
+ end
298
+
299
+ files = ARGV
300
+ files = ['stdin'] if files.size == 0 and not options[:debug]
301
+
302
+ actions = files.map { |f| "load \"#{f.gsub('"', '""')}\"" }
303
+
304
+ if options[:reset] and files.size > 1
305
+ actions = actions.map { |a| [a] }.inject do |sum,a|
306
+ sum += ['reset']
307
+ sum + a
308
+ end.flatten
309
+ end
310
+
311
+ if options[:debug] and actions.size == 0
312
+ actions = ['debug']
313
+ end
314
+
315
+ begin
316
+ ctx.start(actions)
317
+ rescue StandardError => e
318
+ exit false
319
+ ensure
320
+ if ctx.tests.any?
321
+
322
+ if (csv_file = options[:csv])
323
+ total = ctx.tests.size
324
+ ok = ctx.tests.inject(0) { |s,t| s + (t[:status] == 'OK' ? 1 : 0) }
325
+ failed = total - ok
326
+ time = ctx.tests.inject(0) { |s,t| s + t[:time] }
327
+ File.open(ctx.output_path(csv_file), 'w') do |f|
328
+ f.write "Total,OK,Failed,Time\n#{total},#{ok},#{failed},#{time}\n"
329
+ end
330
+ end
331
+
332
+ failed = 0
333
+
334
+ puts
335
+ puts 'Test summary:'
336
+ puts '============='
337
+ puts 'Name'.ljust(40 ) + ' Time'.ljust(7 ) + ' Status'.ljust(7)+' Error'
338
+ puts ''.ljust(40, '-') + ' '.ljust(7, '-') + ' '.ljust(7, '-' )+' '.ljust(5, '-')
339
+ ctx.tests.each do |t|
340
+ error = t[:error]
341
+ error = error ? error.message : ''
342
+ puts t[:name].ljust(40) + ' ' + t[:time].round(2).to_s.rjust(6) + ' ' + t[:status].ljust(6) + ' ' + error
343
+ failed += 1 if t[:status] != 'OK'
344
+ end
345
+ exit failed if failed > 0
346
+ end
347
+ end
348
+ end
349
+ end
350
350
  end