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.
- checksums.yaml +4 -4
- data/LICENSE +21 -21
- data/README.md +293 -293
- data/Rakefile +128 -128
- data/bin/bauxite +27 -27
- data/doc/Bauxite.html +6 -9
- data/doc/Bauxite/Action.html +298 -315
- data/doc/Bauxite/ActionModule.html +23 -26
- data/doc/Bauxite/Application.html +36 -38
- data/doc/Bauxite/Context.html +303 -303
- data/doc/Bauxite/Errors.html +6 -9
- data/doc/Bauxite/Errors/AssertionError.html +6 -9
- data/doc/Bauxite/Errors/FileNotFoundError.html +6 -9
- data/doc/Bauxite/Errors/FormatError.html +6 -9
- data/doc/Bauxite/Loggers.html +6 -9
- data/doc/Bauxite/Loggers/CompositeLogger.html +29 -32
- data/doc/Bauxite/Loggers/EchoLogger.html +10 -13
- data/doc/Bauxite/Loggers/FileLogger.html +25 -28
- data/doc/Bauxite/Loggers/HtmlLogger.html +99 -102
- data/doc/Bauxite/Loggers/NullLogger.html +16 -19
- data/doc/Bauxite/Loggers/ReportLogger.html +43 -46
- data/doc/Bauxite/Loggers/TerminalLogger.html +76 -79
- data/doc/Bauxite/Loggers/XtermLogger.html +28 -31
- data/doc/Bauxite/Parser.html +87 -89
- data/doc/Bauxite/ParserModule.html +19 -22
- data/doc/Bauxite/Selector.html +99 -105
- data/doc/Bauxite/SelectorModule.html +27 -30
- data/doc/README_md.html +117 -103
- data/doc/created.rid +58 -58
- data/doc/fonts.css +167 -167
- data/doc/fonts/Lato-Light.ttf +0 -0
- data/doc/fonts/Lato-LightItalic.ttf +0 -0
- data/doc/fonts/Lato-Regular.ttf +0 -0
- data/doc/fonts/Lato-RegularItalic.ttf +0 -0
- data/doc/fonts/SourceCodePro-Bold.ttf +0 -0
- data/doc/fonts/SourceCodePro-Regular.ttf +0 -0
- data/doc/images/add.png +0 -0
- data/doc/images/arrow_up.png +0 -0
- data/doc/images/brick.png +0 -0
- data/doc/images/brick_link.png +0 -0
- data/doc/images/bug.png +0 -0
- data/doc/images/bullet_black.png +0 -0
- data/doc/images/bullet_toggle_minus.png +0 -0
- data/doc/images/bullet_toggle_plus.png +0 -0
- data/doc/images/date.png +0 -0
- data/doc/images/delete.png +0 -0
- data/doc/images/find.png +0 -0
- data/doc/images/loadingAnimation.gif +0 -0
- data/doc/images/macFFBgHack.png +0 -0
- data/doc/images/package.png +0 -0
- data/doc/images/page_green.png +0 -0
- data/doc/images/page_white_text.png +0 -0
- data/doc/images/page_white_width.png +0 -0
- data/doc/images/plugin.png +0 -0
- data/doc/images/ruby.png +0 -0
- data/doc/images/tag_blue.png +0 -0
- data/doc/images/tag_green.png +0 -0
- data/doc/images/transparent.png +0 -0
- data/doc/images/wrench.png +0 -0
- data/doc/images/wrench_orange.png +0 -0
- data/doc/images/zoom.png +0 -0
- data/doc/index.html +117 -103
- data/doc/js/darkfish.js +32 -11
- data/doc/js/jquery.js +0 -0
- data/doc/js/navigation.js +0 -0
- data/doc/js/search.js +0 -0
- data/doc/js/search_index.js +1 -1
- data/doc/js/searcher.js +0 -0
- data/doc/rdoc.css +580 -580
- data/doc/table_of_contents.html +69 -72
- data/lib/bauxite.rb +28 -28
- data/lib/bauxite/actions/alias.rb +51 -51
- data/lib/bauxite/actions/assert.rb +49 -49
- data/lib/bauxite/actions/asserth.rb +60 -60
- data/lib/bauxite/actions/assertm.rb +49 -49
- data/lib/bauxite/actions/assertv.rb +40 -40
- data/lib/bauxite/actions/assertw.rb +47 -47
- data/lib/bauxite/actions/break.rb +39 -39
- data/lib/bauxite/actions/capture.rb +61 -61
- data/lib/bauxite/actions/click.rb +36 -36
- data/lib/bauxite/actions/debug.rb +103 -103
- data/lib/bauxite/actions/doif.rb +43 -43
- data/lib/bauxite/actions/dounless.rb +43 -43
- data/lib/bauxite/actions/echo.rb +36 -36
- data/lib/bauxite/actions/exec.rb +46 -46
- data/lib/bauxite/actions/exit.rb +35 -35
- data/lib/bauxite/actions/failif.rb +52 -52
- data/lib/bauxite/actions/js.rb +41 -41
- data/lib/bauxite/actions/load.rb +49 -49
- data/lib/bauxite/actions/open.rb +35 -35
- data/lib/bauxite/actions/params.rb +40 -40
- data/lib/bauxite/actions/replace.rb +37 -37
- data/lib/bauxite/actions/reset.rb +38 -38
- data/lib/bauxite/actions/return.rb +68 -68
- data/lib/bauxite/actions/ruby.rb +58 -58
- data/lib/bauxite/actions/select.rb +48 -48
- data/lib/bauxite/actions/set.rb +39 -39
- data/lib/bauxite/actions/setif.rb +44 -44
- data/lib/bauxite/actions/source.rb +44 -44
- data/lib/bauxite/actions/store.rb +38 -38
- data/lib/bauxite/actions/submit.rb +37 -37
- data/lib/bauxite/actions/test.rb +67 -67
- data/lib/bauxite/actions/tryload.rb +71 -71
- data/lib/bauxite/actions/wait.rb +38 -38
- data/lib/bauxite/actions/write.rb +44 -44
- data/lib/bauxite/application.rb +349 -349
- data/lib/bauxite/core/action.rb +199 -199
- data/lib/bauxite/core/context.rb +791 -791
- data/lib/bauxite/core/errors.rb +41 -41
- data/lib/bauxite/core/logger.rb +169 -169
- data/lib/bauxite/core/parser.rb +85 -85
- data/lib/bauxite/core/selector.rb +152 -152
- data/lib/bauxite/loggers/composite.rb +91 -91
- data/lib/bauxite/loggers/echo.rb +36 -36
- data/lib/bauxite/loggers/file.rb +68 -68
- data/lib/bauxite/loggers/html.rb +154 -154
- data/lib/bauxite/loggers/terminal.rb +134 -134
- data/lib/bauxite/loggers/xterm.rb +101 -101
- data/lib/bauxite/parsers/csv.rb +43 -43
- data/lib/bauxite/parsers/default.rb +42 -42
- data/lib/bauxite/parsers/html.rb +79 -79
- data/lib/bauxite/selectors/attr.rb +39 -39
- data/lib/bauxite/selectors/frame.rb +60 -60
- data/lib/bauxite/selectors/json.rb +88 -88
- data/lib/bauxite/selectors/sid.rb +38 -38
- data/lib/bauxite/selectors/smart.rb +80 -80
- data/lib/bauxite/selectors/window.rb +77 -77
- data/test/alert.bxt +3 -3
- data/test/alert/page.html +4 -4
- data/test/alias.bxt +9 -9
- data/test/asserth.bxt +2 -2
- data/test/assertv.bxt +1 -1
- data/test/assertw.bxt +7 -7
- data/test/broken.bxt.manual +0 -0
- data/test/bug_load_path.bxt.manual +0 -0
- data/test/bug_load_path/broken.bxt.manual +0 -0
- data/test/bug_load_path/test.bxt +0 -0
- data/test/capture.bxt.manual +20 -20
- data/test/capture/my_test.bxt +1 -1
- data/test/capture/page.html +6 -6
- data/test/capture_on_error.bxt.manual +3 -3
- data/test/capture_on_error/my_test.bxt +1 -1
- data/test/capture_on_error/page.html +2 -2
- data/test/debug.bxt.manual +0 -0
- data/test/default_selector.bxt.manual +7 -7
- data/test/default_selector/page.html +10 -10
- data/test/default_selector_var.bxt +1 -1
- data/test/delay.bxt +2 -2
- data/test/delay/page.html +4 -4
- data/test/doif.bxt +6 -6
- data/test/dounless.bxt +6 -6
- data/test/exec.bxt +6 -6
- data/test/exit.bxt +3 -3
- data/test/exit/test.bxt +3 -3
- data/test/extension.bxt.manual +4 -4
- data/test/extension/custom.rb +12 -12
- data/test/extension/page.html +4 -4
- data/test/failif.bxt +7 -7
- data/test/failif/page.html +5 -5
- data/test/format.bxt +17 -17
- data/test/format/page.html +6 -6
- data/test/frame.bxt +6 -6
- data/test/frame/child_frame.html +6 -6
- data/test/frame/grandchild_frame.html +4 -4
- data/test/frame/page.html +4 -4
- data/test/js.bxt +4 -4
- data/test/json.bxt +19 -19
- data/test/json/array.json +3 -3
- data/test/json/object.json +13 -13
- data/test/load.bxt +18 -18
- data/test/load/child.bxt +12 -12
- data/test/parsers.bxt +1 -1
- data/test/parsers.csv +7 -7
- data/test/parsers.html +32 -32
- data/test/parsers/page.html +6 -6
- data/test/return.bxt +1 -1
- data/test/return/f1.bxt +1 -1
- data/test/return/f2.bxt +1 -1
- data/test/return/f3.bxt +1 -1
- data/test/return/f4.bxt +2 -2
- data/test/ruby.bxt +1 -1
- data/test/ruby/custom.rb +5 -5
- data/test/select.bxt +9 -9
- data/test/select/page.html +8 -8
- data/test/selectors.bxt +7 -7
- data/test/selectors/page.html +6 -6
- data/test/set_builtin.bxt +5 -0
- data/test/set_builtin/page.html +5 -0
- data/test/setif.bxt +3 -3
- data/test/smart_selector.bxt +17 -17
- data/test/smart_selector/page.html +17 -17
- data/test/stdin.bxt +0 -0
- data/test/submit.bxt +4 -4
- data/test/submit/page.html +6 -6
- data/test/submit/page2.html +4 -4
- data/test/test.bxt.manual +6 -6
- data/test/test/test1.bxt +2 -2
- data/test/test/test2.bxt +3 -3
- data/test/test/test3.bxt +2 -2
- data/test/test/test4.bxt +1 -1
- data/test/test/test5.bxt +1 -1
- data/test/window.bxt +14 -14
- data/test/window/page.html +5 -5
- data/test/window/popup.html +4 -4
- metadata +5 -3
data/lib/bauxite/actions/wait.rb
CHANGED
@@ -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
|
data/lib/bauxite/application.rb
CHANGED
@@ -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
|