bauxite 0.6.18 → 0.6.19

Sign up to get free protection for your applications and to get access to all the features.
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