bauxite 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE +21 -0
- data/Rakefile +69 -0
- data/bin/bauxite +27 -0
- data/doc/Bauxite/Action.html +1463 -0
- data/doc/Bauxite/ActionModule.html +342 -0
- data/doc/Bauxite/Context.html +1439 -0
- data/doc/Bauxite/Errors/AssertionError.html +107 -0
- data/doc/Bauxite/Errors/FileNotFoundError.html +107 -0
- data/doc/Bauxite/Errors.html +100 -0
- data/doc/Bauxite/Loggers/CompositeLogger.html +325 -0
- data/doc/Bauxite/Loggers/EchoLogger.html +164 -0
- data/doc/Bauxite/Loggers/FileLogger.html +215 -0
- data/doc/Bauxite/Loggers/NullLogger.html +334 -0
- data/doc/Bauxite/Loggers/TerminalLogger.html +586 -0
- data/doc/Bauxite/Loggers/XtermLogger.html +287 -0
- data/doc/Bauxite/Loggers.html +103 -0
- data/doc/Bauxite/Selector.html +422 -0
- data/doc/Bauxite/SelectorModule.html +283 -0
- data/doc/Bauxite.html +98 -0
- data/doc/created.rid +37 -0
- 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/fonts.css +167 -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 +111 -0
- data/doc/js/darkfish.js +140 -0
- data/doc/js/jquery.js +18 -0
- data/doc/js/navigation.js +142 -0
- data/doc/js/search.js +109 -0
- data/doc/js/search_index.js +1 -0
- data/doc/js/searcher.js +228 -0
- data/doc/rdoc.css +580 -0
- data/doc/table_of_contents.html +510 -0
- data/lib/bauxite/actions/alias.rb +51 -0
- data/lib/bauxite/actions/assert.rb +49 -0
- data/lib/bauxite/actions/assertv.rb +40 -0
- data/lib/bauxite/actions/break.rb +39 -0
- data/lib/bauxite/actions/click.rb +35 -0
- data/lib/bauxite/actions/debug.rb +99 -0
- data/lib/bauxite/actions/echo.rb +36 -0
- data/lib/bauxite/actions/exec.rb +46 -0
- data/lib/bauxite/actions/js.rb +41 -0
- data/lib/bauxite/actions/load.rb +49 -0
- data/lib/bauxite/actions/open.rb +34 -0
- data/lib/bauxite/actions/params.rb +40 -0
- data/lib/bauxite/actions/replace.rb +37 -0
- data/lib/bauxite/actions/reset.rb +37 -0
- data/lib/bauxite/actions/return.rb +62 -0
- data/lib/bauxite/actions/ruby.rb +58 -0
- data/lib/bauxite/actions/set.rb +39 -0
- data/lib/bauxite/actions/source.rb +44 -0
- data/lib/bauxite/actions/store.rb +38 -0
- data/lib/bauxite/actions/test.rb +61 -0
- data/lib/bauxite/actions/tryload.rb +79 -0
- data/lib/bauxite/actions/wait.rb +38 -0
- data/lib/bauxite/actions/write.rb +40 -0
- data/lib/bauxite/application.rb +150 -0
- data/lib/bauxite/core/Action.rb +205 -0
- data/lib/bauxite/core/Context.rb +575 -0
- data/lib/bauxite/core/Errors.rb +36 -0
- data/lib/bauxite/core/Logger.rb +86 -0
- data/lib/bauxite/core/Selector.rb +156 -0
- data/lib/bauxite/loggers/composite.rb +70 -0
- data/lib/bauxite/loggers/echo.rb +36 -0
- data/lib/bauxite/loggers/file.rb +45 -0
- data/lib/bauxite/loggers/terminal.rb +130 -0
- data/lib/bauxite/loggers/xterm.rb +79 -0
- data/lib/bauxite/selectors/attr.rb +39 -0
- data/lib/bauxite/selectors/default.rb +38 -0
- data/lib/bauxite/selectors/frame.rb +60 -0
- data/lib/bauxite.rb +29 -0
- data/test/alias.bxt +6 -0
- data/test/assertv.bxt +2 -0
- data/test/delay/page.html +5 -0
- data/test/delay.bxt +2 -0
- data/test/exec.bxt +6 -0
- data/test/format/page.html +7 -0
- data/test/format.bxt +17 -0
- data/test/frame/child_frame.html +7 -0
- data/test/frame/grandchild_frame.html +5 -0
- data/test/frame/page.html +5 -0
- data/test/frame.bxt +6 -0
- data/test/js.bxt +5 -0
- data/test/load/child.bxt +13 -0
- data/test/load.bxt +17 -0
- data/test/ruby/custom.rb +5 -0
- data/test/ruby.bxt +2 -0
- data/test/selectors/page.html +7 -0
- data/test/selectors.bxt +7 -0
- data/test/stdin.bxt +1 -0
- data/test/test/test1.bxt +2 -0
- data/test/test/test2.bxt +3 -0
- data/test/test/test3.bxt +2 -0
- data/test/test.bxt.manual +4 -0
- metadata +194 -0
@@ -0,0 +1,156 @@
|
|
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
|
+
module Bauxite
|
24
|
+
# Selector common state and behavior.
|
25
|
+
module SelectorModule
|
26
|
+
|
27
|
+
# Constructs a new test selector instance.
|
28
|
+
def initialize(ctx)
|
29
|
+
@ctx = ctx
|
30
|
+
end
|
31
|
+
|
32
|
+
# Searches for elements using the specified selector string.
|
33
|
+
#
|
34
|
+
# For more information see Context#find.
|
35
|
+
#
|
36
|
+
# Selectors calling this method should forward their block as well.
|
37
|
+
#
|
38
|
+
# For example:
|
39
|
+
# # === selectors/example.rb ======= #
|
40
|
+
# class Selector
|
41
|
+
# # :category: Selector Methods
|
42
|
+
# def example(arg, &block)
|
43
|
+
# find(arg, &block)
|
44
|
+
# end
|
45
|
+
# end
|
46
|
+
# # === end selectors/example.rb === #
|
47
|
+
#
|
48
|
+
def find(selector, &block)
|
49
|
+
# I know I should be using Class scope operators to refer to class
|
50
|
+
# methods (i.e. Context::selectors), but for some reason RDoc
|
51
|
+
# refuses to document the Selector class (below) if any such
|
52
|
+
# operators appear in this method (quite strange). So for now, I'll
|
53
|
+
# just settle for using the old and trusty "."
|
54
|
+
|
55
|
+
data = selector.split('=', 2)
|
56
|
+
type = data.length == 2 ? data[0] : "default"
|
57
|
+
raise ArgumentError, "Invalid selector type '#{type}'" unless Context.selectors.include? type
|
58
|
+
|
59
|
+
arg = data[-1]
|
60
|
+
custom_selectors = Context.selectors(false)
|
61
|
+
return send(type , arg, &block) if custom_selectors.include? type
|
62
|
+
return send(type+'_selector', arg, &block) if custom_selectors.include? type+'_selector'
|
63
|
+
selenium_find(type, arg, &block)
|
64
|
+
end
|
65
|
+
|
66
|
+
protected
|
67
|
+
# Searches for elements using standard Selenium selectors.
|
68
|
+
#
|
69
|
+
# Selectors calling this method should forward their block as well.
|
70
|
+
#
|
71
|
+
# # === selectors/data.rb ======= #
|
72
|
+
# class Selector
|
73
|
+
# # :category: Selector Methods
|
74
|
+
# def data(arg, &block)
|
75
|
+
# # selector code goes here, for example:
|
76
|
+
# selenium_find(:css, "[data='#{arg}']", &block)
|
77
|
+
# end
|
78
|
+
# end
|
79
|
+
# # === end selectors/data.rb === #
|
80
|
+
#
|
81
|
+
def selenium_find(type, selector)
|
82
|
+
element = @ctx.driver.find_element(type, selector)
|
83
|
+
yield element if block_given?
|
84
|
+
element
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
# Selector class.
|
89
|
+
#
|
90
|
+
# Selectors represent different strategies for finding elements. Selenium
|
91
|
+
# provides a list of standard selectors (e.g. by id, by css expression, etc).
|
92
|
+
#
|
93
|
+
# Additional selectors can be specified by defining custom methods in the
|
94
|
+
# Selector class.
|
95
|
+
#
|
96
|
+
# Each custom selector is defined in a separate file in the 'selectors/'
|
97
|
+
# directory.
|
98
|
+
# The name of the file must match the name of the selector. These files should
|
99
|
+
# avoid adding public methods other than the selector method itself.
|
100
|
+
# Also, no +attr_accessors+ should be added.
|
101
|
+
#
|
102
|
+
# Selector methods can use the +ctx+ attribute to refer to the current test
|
103
|
+
# Context. The protected method #selenium_find can also be used to locate elements
|
104
|
+
# using standard Selenium selectors.
|
105
|
+
#
|
106
|
+
# Selector methods should always take a block and forward that block to a call
|
107
|
+
# to either #find or #selenium_find.
|
108
|
+
#
|
109
|
+
# For example (new selector template):
|
110
|
+
# # === selectors/data.rb ======= #
|
111
|
+
# class Selector
|
112
|
+
# # :category: Selector Methods
|
113
|
+
# def data(arg, &block)
|
114
|
+
# # selector code goes here, for example:
|
115
|
+
# selenium_find(:css, "[data='#{arg}']", &block)
|
116
|
+
# end
|
117
|
+
# end
|
118
|
+
# # === end selectors/data.rb === #
|
119
|
+
#
|
120
|
+
# Context::selectors.include? 'data' # => true
|
121
|
+
#
|
122
|
+
# To avoid name clashing with Ruby reserved words, the '_selector' suffix can
|
123
|
+
# be included in the selector method name (this suffix will not be considered
|
124
|
+
# part of the selector name).
|
125
|
+
#
|
126
|
+
# For example (_selector suffix):
|
127
|
+
# # === selectors/end.rb ======= #
|
128
|
+
# class Selector
|
129
|
+
# # :category: Selector Methods
|
130
|
+
# def end_selector
|
131
|
+
# # do something
|
132
|
+
# end
|
133
|
+
# end
|
134
|
+
# # === end selector/end.rb === #
|
135
|
+
#
|
136
|
+
# Context::selectors.include? 'end' # => true
|
137
|
+
#
|
138
|
+
# ---
|
139
|
+
#
|
140
|
+
# === Standard Selenium Selectors
|
141
|
+
#
|
142
|
+
# [id=+targetValue+] {Locate elements whose +id+ attribute matches +targetValue+.}[http://docs.seleniumhq.org/docs/03_webdriver.jsp#by-id]
|
143
|
+
# [name=+targetValue+] {Locate elements whose +name+ attribute matches +targetValue+.}[http://docs.seleniumhq.org/docs/03_webdriver.jsp#by-name]
|
144
|
+
# [css=+cssSelectorSyntax+] {Locate elements using CSS selector syntax.}[http://docs.seleniumhq.org/docs/03_webdriver.jsp#by-css]
|
145
|
+
# [partial_link_text=+textFragment+] {Locate A elements whose text includes +textFragment+.}[http://docs.seleniumhq.org/docs/03_webdriver.jsp#by-partial-link-text]
|
146
|
+
# [class=+className+ and class_name=+className+] {Locate elements whose +class+ attribute matches +className+.}[http://docs.seleniumhq.org/docs/03_webdriver.jsp#by-class-name]
|
147
|
+
# [link=+exactText+ and link_text=+exactText+] {Locate A elements whose text is exactly +exactText+.}[http://docs.seleniumhq.org/docs/03_webdriver.jsp#by-link-text]
|
148
|
+
# [tag_name=+targetValue+] {Locate elements whose tag name matches +targetValue+.}[http://docs.seleniumhq.org/docs/03_webdriver.jsp#by-tag-name]
|
149
|
+
# [xpath=+xpathExpression+] {Locate elements using XPATH expressions.}[http://docs.seleniumhq.org/docs/03_webdriver.jsp#by-xpath]
|
150
|
+
#
|
151
|
+
class Selector
|
152
|
+
include SelectorModule
|
153
|
+
|
154
|
+
# :section: Selector Methods
|
155
|
+
end
|
156
|
+
end
|
@@ -0,0 +1,70 @@
|
|
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
|
+
# Composite logger.
|
24
|
+
#
|
25
|
+
# This composite logger forwards logging calls to each of its children.
|
26
|
+
#
|
27
|
+
# Set the +:loggers+ option to a comma-separated list of logger names
|
28
|
+
#
|
29
|
+
class Bauxite::Loggers::CompositeLogger
|
30
|
+
|
31
|
+
# Constructs a new composite logger instance.
|
32
|
+
def initialize(options)
|
33
|
+
@loggers = options[:loggers].split(',').map do |l|
|
34
|
+
Bauxite::Context::load_logger(l, options)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# Pretty prints action information and status.
|
39
|
+
#
|
40
|
+
# This implementation only yileds in the first logger.
|
41
|
+
#
|
42
|
+
# Additional loggers are called after the block completed.
|
43
|
+
#
|
44
|
+
def log_cmd(action, &block)
|
45
|
+
ret = @loggers[0].log_cmd(action, &block)
|
46
|
+
@loggers[1..-1].each { |l| l.log_cmd(action) { ret } }
|
47
|
+
ret
|
48
|
+
end
|
49
|
+
|
50
|
+
# Returns a colorized debug prompt.
|
51
|
+
#
|
52
|
+
# This implementation returns the debug_prompt of the first logger.
|
53
|
+
#
|
54
|
+
def debug_prompt
|
55
|
+
@loggers[0].debug_prompt
|
56
|
+
end
|
57
|
+
|
58
|
+
# Updates action progress.
|
59
|
+
def progress(value)
|
60
|
+
@loggers.each { |l| l.progress(value) }
|
61
|
+
end
|
62
|
+
|
63
|
+
# Prints the specified string.
|
64
|
+
#
|
65
|
+
# See Bauxite::Loggers::NullLogger#print
|
66
|
+
#
|
67
|
+
def log(s, type = :info)
|
68
|
+
@loggers.each { |l| l.log(s, type) }
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,36 @@
|
|
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
|
+
# Echo logger.
|
24
|
+
#
|
25
|
+
# This logger outputs the raw action text for every action executed.
|
26
|
+
#
|
27
|
+
# Note that this logger does not include execution status information
|
28
|
+
# (i.e. action succeeded, failed or was skipped).
|
29
|
+
#
|
30
|
+
class Bauxite::Loggers::EchoLogger < Bauxite::Loggers::NullLogger
|
31
|
+
# Echoes the raw action text.
|
32
|
+
def log_cmd(action)
|
33
|
+
puts action.text
|
34
|
+
yield
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,45 @@
|
|
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
|
+
# File logger.
|
24
|
+
#
|
25
|
+
# This logger outputs the raw action text for every action executed to
|
26
|
+
# the file specified in the +file+ logger option.
|
27
|
+
#
|
28
|
+
class Bauxite::Loggers::FileLogger < Bauxite::Loggers::NullLogger
|
29
|
+
|
30
|
+
# Constructs a new echo logger instance.
|
31
|
+
def initialize(options)
|
32
|
+
super(options)
|
33
|
+
@file = options[:file]
|
34
|
+
unless @file and @file != ''
|
35
|
+
raise ArgumentError, "FileLogger configuration error: Undefined 'file' option."
|
36
|
+
end
|
37
|
+
File.open(@file, "w") {} # truncate file
|
38
|
+
end
|
39
|
+
|
40
|
+
# Echoes the raw action text.
|
41
|
+
def log_cmd(action)
|
42
|
+
File.open(@file, 'a+') { |f| f.write(action.text+"\n") }
|
43
|
+
yield
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,130 @@
|
|
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
|
+
# Terminal logger.
|
24
|
+
#
|
25
|
+
# This logger outputs text using basic text formatting for a terminal
|
26
|
+
# window.
|
27
|
+
#
|
28
|
+
class Bauxite::Loggers::TerminalLogger < Bauxite::Loggers::NullLogger
|
29
|
+
# Constructs a new Terminal logger instance.
|
30
|
+
def initialize(options)
|
31
|
+
super(options)
|
32
|
+
@max_cmd_size = Bauxite::Context::max_action_name_size
|
33
|
+
end
|
34
|
+
|
35
|
+
# Pretty prints action information and status.
|
36
|
+
def log_cmd(action)
|
37
|
+
width = _screen_width
|
38
|
+
cmd = action.cmd.downcase
|
39
|
+
color = _cmd_color(cmd)
|
40
|
+
cmd = cmd.ljust(@max_cmd_size)
|
41
|
+
max_args_size = width-cmd.size-1-6-1-1
|
42
|
+
|
43
|
+
print "#{_fmt(color, cmd)} "
|
44
|
+
s = action.args(true).join(' ')
|
45
|
+
s = s[0...max_args_size-3]+'...' if s.size > max_args_size
|
46
|
+
print s.ljust(max_args_size)
|
47
|
+
_save_cursor
|
48
|
+
color = :green
|
49
|
+
text = 'OK'
|
50
|
+
ret = yield
|
51
|
+
if not ret
|
52
|
+
color = :yellow
|
53
|
+
text = 'SKIP'
|
54
|
+
end
|
55
|
+
_restore_cursor
|
56
|
+
puts " #{_block(color, text, 5)}"
|
57
|
+
ret
|
58
|
+
rescue
|
59
|
+
_restore_cursor
|
60
|
+
puts " #{_block(:red, 'ERROR', 5)}"
|
61
|
+
raise
|
62
|
+
end
|
63
|
+
|
64
|
+
# Returns a colorized debug prompt.
|
65
|
+
def debug_prompt
|
66
|
+
_fmt(:white, super)
|
67
|
+
end
|
68
|
+
|
69
|
+
# Updates action progress.
|
70
|
+
def progress(value)
|
71
|
+
if _restore_cursor
|
72
|
+
print " #{_block(:gray, value.to_s, 5)}"
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
# Prints the specified string.
|
77
|
+
#
|
78
|
+
# See Bauxite::Loggers::NullLogger#print
|
79
|
+
#
|
80
|
+
def log(s, type = :info)
|
81
|
+
color = :gray
|
82
|
+
case type
|
83
|
+
when :error
|
84
|
+
color = :red
|
85
|
+
when :warning
|
86
|
+
color = :yellow
|
87
|
+
when :debug
|
88
|
+
color = :purple
|
89
|
+
end
|
90
|
+
super _fmt(color, s), type
|
91
|
+
end
|
92
|
+
|
93
|
+
protected
|
94
|
+
# Centers +text+ to a fixed size with.
|
95
|
+
def _fmt(color, text, size = 0)
|
96
|
+
text.center(size)
|
97
|
+
end
|
98
|
+
|
99
|
+
# Save the current cursor position,
|
100
|
+
def _save_cursor
|
101
|
+
false
|
102
|
+
end
|
103
|
+
|
104
|
+
# Restores the cursor to the previously saved cursor position.
|
105
|
+
def _restore_cursor
|
106
|
+
false
|
107
|
+
end
|
108
|
+
|
109
|
+
# Prints +text+ centered inside a square-bracketed block.
|
110
|
+
def _block(color, text, size)
|
111
|
+
"#{_fmt(:white, '[')}#{_fmt(color, text, size)}#{_fmt(:white, ']')}"
|
112
|
+
end
|
113
|
+
|
114
|
+
# Get the color of +cmd+.
|
115
|
+
def _cmd_color(cmd)
|
116
|
+
case cmd
|
117
|
+
when 'load'
|
118
|
+
return :cyan
|
119
|
+
when 'test'
|
120
|
+
return :purple
|
121
|
+
else
|
122
|
+
return :blue
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
# Returns the terminal screen width.
|
127
|
+
def _screen_width
|
128
|
+
80
|
129
|
+
end
|
130
|
+
end
|
@@ -0,0 +1,79 @@
|
|
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_relative 'terminal'
|
24
|
+
|
25
|
+
# XTerm logger.
|
26
|
+
#
|
27
|
+
# This logger outputs colorized lines using xterm (VT100/2) escape
|
28
|
+
# sequences.
|
29
|
+
#
|
30
|
+
class Bauxite::Loggers::XtermLogger < Bauxite::Loggers::TerminalLogger
|
31
|
+
|
32
|
+
protected
|
33
|
+
COLORS = { # :nodoc:
|
34
|
+
:black => '0;30',
|
35
|
+
:dark_blue => '0;34',
|
36
|
+
:dark_green => '0;32',
|
37
|
+
:dark_cyan => '0;36',
|
38
|
+
:dark_red => '0;31',
|
39
|
+
:dark_purple => '0;35',
|
40
|
+
:dark_brown => '0;33',
|
41
|
+
:dark_gray => '1;30',
|
42
|
+
:gray => '0;37',
|
43
|
+
:blue => '1;34',
|
44
|
+
:green => '1;32',
|
45
|
+
:cyan => '1;36',
|
46
|
+
:red => '1;31',
|
47
|
+
:purple => '1;35',
|
48
|
+
:yellow => '1;33',
|
49
|
+
:white => '1;37'
|
50
|
+
}
|
51
|
+
|
52
|
+
def _fmt(color, text, size = 0)
|
53
|
+
text = super(color, text, size)
|
54
|
+
if @options[:nc] or @options[:color] == 'no'
|
55
|
+
text
|
56
|
+
else
|
57
|
+
"\033[#{COLORS[color]}m#{text}\033[0m"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def _save_cursor
|
62
|
+
print "\033[s"
|
63
|
+
true
|
64
|
+
end
|
65
|
+
|
66
|
+
def _restore_cursor
|
67
|
+
print "\033[u"
|
68
|
+
true
|
69
|
+
end
|
70
|
+
|
71
|
+
def _screen_width
|
72
|
+
begin
|
73
|
+
require 'terminfo'
|
74
|
+
TermInfo.screen_size[1]
|
75
|
+
rescue Exception
|
76
|
+
super
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,39 @@
|
|
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::Selector
|
24
|
+
# Select an element by attribute value.
|
25
|
+
#
|
26
|
+
# The attribute selector syntax is:
|
27
|
+
# attr=name:value
|
28
|
+
#
|
29
|
+
# For example:
|
30
|
+
# # assuming <div custom="true">foo</div>
|
31
|
+
# assert attr=custom:true "foo"
|
32
|
+
# # => matches the element above.
|
33
|
+
#
|
34
|
+
# :category: Selector Methods
|
35
|
+
def attr(arg, &block)
|
36
|
+
data = arg.split(':', 2)
|
37
|
+
selenium_find(:css, "[#{data[0]}='#{data[1]}']", &block)
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +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::Selector
|
24
|
+
# Select an element by id suffix.
|
25
|
+
#
|
26
|
+
# This is the default selector. Any selector strings that do not contain an
|
27
|
+
# equal sign (i.e. '=') will use this selector.
|
28
|
+
#
|
29
|
+
# For example:
|
30
|
+
# # assuming <div id="strange_uuid_like_stuff_myDiv">foo</div>
|
31
|
+
# assert myDiv "foo"
|
32
|
+
# # => matches the element above.
|
33
|
+
#
|
34
|
+
# :category: Selector Methods
|
35
|
+
def default(arg, &block)
|
36
|
+
selenium_find(:css, "[id$='#{arg.gsub("'", "\\'")}']", &block)
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,60 @@
|
|
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::Selector
|
24
|
+
# Change the selector scope to the given frame and finds an element in that
|
25
|
+
# frame.
|
26
|
+
#
|
27
|
+
# This is a composite selector. The frame selector syntax is:
|
28
|
+
# frame=|frame_selector|child_selector
|
29
|
+
#
|
30
|
+
# Where +frame_selector+ is any selector available that matches the target
|
31
|
+
# frame, +child_selector+ is any selector available that matches the target
|
32
|
+
# element inside the target frame.
|
33
|
+
#
|
34
|
+
# Note that the '|' character can be replaced with any single-character
|
35
|
+
# delimiter.
|
36
|
+
#
|
37
|
+
# Also note that frame selectors can be embedded to select a frame inside
|
38
|
+
# a frame. To accompilish this, +child_selector+ can be a frame selector.
|
39
|
+
#
|
40
|
+
# For example:
|
41
|
+
# # assuming <iframe class="myframe">
|
42
|
+
# # <div id="child">foo</div>
|
43
|
+
# # </iframe>
|
44
|
+
# assert "frame=|css=.myframe|child" "foo"
|
45
|
+
# # => matches the 'child' element above.
|
46
|
+
#
|
47
|
+
# :category: Selector Methods
|
48
|
+
def frame(arg, &block)
|
49
|
+
delimiter = arg[0]
|
50
|
+
items = arg[1..-1].split(delimiter, 2)
|
51
|
+
frame = find(items[0])
|
52
|
+
|
53
|
+
begin
|
54
|
+
@ctx.driver.switch_to.frame frame
|
55
|
+
find(items[1], &block)
|
56
|
+
ensure
|
57
|
+
@ctx.driver.switch_to.default_content
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
data/lib/bauxite.rb
ADDED
@@ -0,0 +1,29 @@
|
|
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
|
+
#--
|
24
|
+
module Bauxite
|
25
|
+
VERSION = "0.1.0"
|
26
|
+
end
|
27
|
+
#++
|
28
|
+
|
29
|
+
require_relative 'bauxite/application'
|