Class: Dill::Widget
- Inherits:
-
Object
- Object
- Dill::Widget
- Extended by:
- Forwardable
- Includes:
- WidgetContainer
- Defined in:
- lib/dill/widget.rb
Direct Known Subclasses
AutoTable::Row, BaseTable, FieldGroup, FieldGroup::Field, List
Defined Under Namespace
Instance Attribute Summary collapse
-
#root ⇒ Object
readonly
The root node of the current widget.
Widget macros collapse
-
.action(name, selector) ⇒ Object
Defines a new action.
-
.widget(name, *rest) { ... } ⇒ Object
Declares a new child widget.
-
.widget_delegator(name, widget_message, method_name = nil) ⇒ Object
Creates a delegator for one child widget message.
Class Method Summary collapse
-
.find_in(node, options = {}) ⇒ Object
Finds a single instance of the current widget in
node. -
.present_in?(parent_node) ⇒ Boolean
Determines if an instance of this widget class exists in
parent_node. -
.root(selector) ⇒ Object
Sets this widget’s default selector.
-
.selector ⇒ Object
The selector specified with
root.
Instance Method Summary collapse
-
#!=(value) ⇒ Object
Compares the current widget with
value, waiting for the comparison to returnfalse. -
#==(value) ⇒ Object
Compares the current widget with
value, waiting for the comparison to returntrue. -
#has_action?(name) ⇒ Boolean
Determines if the widget underlying an action exists.
-
#initialize(settings = {}) ⇒ Widget
constructor
A new instance of Widget.
- #inspect ⇒ Object
-
#reload(wait_time = Capybara.default_wait_time) { ... } ⇒ Object
Reloads the widget, waiting for its contents to change (by default), or until
wait_timeexpires. - #to_f ⇒ Object
- #to_i ⇒ Object
- #to_s ⇒ Object
Methods included from WidgetContainer
Constructor Details
#initialize(settings = {}) ⇒ Widget
Returns a new instance of Widget.
215 216 217 |
# File 'lib/dill/widget.rb', line 215 def initialize(settings = {}) self.root = settings.fetch(:root) end |
Instance Attribute Details
#root ⇒ Object
Returns The root node of the current widget.
211 212 213 |
# File 'lib/dill/widget.rb', line 211 def root @root end |
Class Method Details
.action(name, selector) ⇒ Object
Defines a new action.
This is a shortcut to help defining a widget and a method that clicks on that widget. You can then send a widget instance the message given by name.
You can access the underlying widget by appending “_widget” to the action name.
44 45 46 47 48 49 50 51 52 53 54 |
# File 'lib/dill/widget.rb', line 44 def self.action(name, selector) wname = :"#{name}_widget" wname, selector define_method name do (wname).click self end end |
.find_in(node, options = {}) ⇒ Object
Finds a single instance of the current widget in node.
184 185 186 |
# File 'lib/dill/widget.rb', line 184 def self.find_in(node, = {}) new(.merge(root: node.find(selector))) end |
.present_in?(parent_node) ⇒ Boolean
Determines if an instance of this widget class exists in parent_node.
194 195 196 |
# File 'lib/dill/widget.rb', line 194 def self.present_in?(parent_node) parent_node.has_selector?(selector) end |
.root(selector) ⇒ Object
Sets this widget’s default selector.
201 202 203 |
# File 'lib/dill/widget.rb', line 201 def self.root(selector) @selector = selector end |
.selector ⇒ Object
Returns The selector specified with root.
206 207 208 |
# File 'lib/dill/widget.rb', line 206 def self.selector @selector end |
.widget(name, selector, type = Widget) ⇒ Object .widget(name, type) ⇒ Object
Declares a new child widget.
Child widgets are accessible inside the container widget using the Dill::WidgetContainer#widget message, or by sending a message name. They are automatically scoped to the parent widget’s root node.
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 |
# File 'lib/dill/widget.rb', line 105 def self.(name, *rest, &block) raise ArgumentError, "`#{name}' is a reserved name" \ if WidgetContainer.instance_methods.include?(name.to_sym) case rest.first when Class arg_count = rest.size + 1 raise ArgumentError, "wrong number of arguments (#{arg_count} for 2)" \ unless arg_count == 2 type = rest.first raise TypeError, "can't convert `#{type}' to Widget" \ unless type.methods.include?(:selector) raise ArgumentError, "missing root selector for `#{type}'" \ unless type.selector selector = type.selector when String arg_count = rest.size + 1 case arg_count when 0, 1 raise ArgumentError, "wrong number of arguments (#{arg_count} for 2)" when 2 selector, type = [*rest, Widget] when 3 selector, type = rest raise TypeError, "can't convert `#{type}' to Widget" \ unless Class === type else raise ArgumentError, "wrong number of arguments (#{arg_count} for 3)" end else raise ArgumentError, "unknown method signature: #{rest.inspect}" end child = Class.new(type) { root selector } child.class_eval(&block) if block_given? const_set(Dill::WidgetName.new(name).to_sym, child) define_method name do (name) end end |
.widget_delegator(name, widget_message, method_name = nil) ⇒ Object
Creates a delegator for one child widget message.
Since widgets are accessed through Dill::WidgetContainer#widget, we can’t use Forwardable to delegate messages to widgets.
161 162 163 164 165 166 167 168 169 170 171 172 173 |
# File 'lib/dill/widget.rb', line 161 def self.(name, , method_name = nil) method_name = method_name || class_eval " def \#{method_name}(*args)\n if args.size == 1\n widget(:\#{name}).\#{widget_message} args.first\n else\n widget(:\#{name}).\#{widget_message} *args\n end\n end\n RUBY\nend\n" |
Instance Method Details
#!=(value) ⇒ Object
Compares the current widget with value, waiting for the comparison to return false.
227 228 229 |
# File 'lib/dill/widget.rb', line 227 def !=(value) checkpoint.wait_until(false) { cast_to(value) != value } end |
#==(value) ⇒ Object
Compares the current widget with value, waiting for the comparison to return true.
221 222 223 |
# File 'lib/dill/widget.rb', line 221 def ==(value) checkpoint.wait_until(false) { cast_to(value) == value } end |
#has_action?(name) ⇒ Boolean
Determines if the widget underlying an action exists.
243 244 245 246 247 |
# File 'lib/dill/widget.rb', line 243 def has_action?(name) raise Missing, "couldn't find `#{name}' action" unless respond_to?(name) (:"#{name}_widget") end |
#inspect ⇒ Object
249 250 251 252 253 254 255 256 257 258 |
# File 'lib/dill/widget.rb', line 249 def inspect root = self.root xml = Nokogiri::HTML(page.body).at(root.path).to_xml "<!-- #{self.class.name}: -->\n" << Nokogiri::XML(xml, &:noblanks).to_xhtml rescue ::NotSupportedByDriverError root.inspect end |
#reload(wait_time = Capybara.default_wait_time) { ... } ⇒ Object
Reloads the widget, waiting for its contents to change (by default), or until wait_time expires.
Call this method to make sure a widget has enough time to update itself.
You can pass a block to this method to control what it means for the widget to be reloaded.
*Note: does not account for multiple changes to the widget yet.*
284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 |
# File 'lib/dill/widget.rb', line 284 def reload(wait_time = .default_wait_time, &test) unless test old_root = root test = ->{ old_root != root } end checkpoint(wait_time).wait_until(false, &test) begin root.inspect rescue raise Removed, "widget was removed" end self end |
#to_f ⇒ Object
305 306 307 |
# File 'lib/dill/widget.rb', line 305 def to_f to_s.to_f end |
#to_i ⇒ Object
301 302 303 |
# File 'lib/dill/widget.rb', line 301 def to_i to_s.to_i end |
#to_s ⇒ Object
309 310 311 |
# File 'lib/dill/widget.rb', line 309 def to_s node_text(root) end |