Class: Domino

Inherits:
Object
  • Object
show all
Extended by:
Capybara::DSL, Enumerable
Includes:
Capybara::DSL
Defined in:
lib/domino.rb

Overview

To create a basic Domino class, inherit from Domino and define a selector and attributes:

module Dom
  class Post < Domino
    selector '#posts .post'
    attribute :title # selector defaults to .title
    attribute :body, '.post-body' # example of selector override

    # can define attributes on the selected node
    attribute :uuid, "&[data-uuid]"

    # can define states based on classes of the selected node
    attribute :active, "&.active"

    # accepts blocks as callbacks these are run only if attribute exists
    attribute :comments do |text|
      text.to_i
    end
  end
end

Now in your integration test you can use some of Domino's methods:

assert_equal 4, Dom::Post.count
refute_nil Dom::Post.find_by_title('First Post')

What makes it really powerful is defining scoped actions:

module Dom
  class Post < Domino
    def delete
      within(id) { click_button 'Delete' }
    end
  end
end

refute_nil Dom::Post.find_by_title('First Post')
Dom::Post.find_by_title('First Post').delete
assert_nil Dom::Post.find_by_title('First Post')

Direct Known Subclasses

Form

Defined Under Namespace

Classes: Attribute, Error, Form

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#nodeObject (readonly)

Direct access to the capybara node, in case you need anything special



54
55
56
# File 'lib/domino.rb', line 54

def node
  @node
end

Class Method Details

.allObject

Get an array of all the Dominos



67
68
69
# File 'lib/domino.rb', line 67

def all
  map { |domino| domino }
end

.attribute(attribute, selector = nil, &callback) ⇒ Object

Define an attribute for this Domino

module Dom
  class Post
    attribute :title # defaults to selector '.title'
    attribute :body, '.post-body' # use a custom selector
  end
end

This will define an attr_reader on the Domino and also a find_by_attribute method:

Dom::Post.all.first.title
Dom::Post.find_by_title("First Post")
Dom::Post.find_by_title(/^First/)


136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
# File 'lib/domino.rb', line 136

def attribute(attribute, selector = nil, &callback)
  selector ||= %(.#{attribute.to_s.tr('_', '-')})

  attribute_definitions[attribute] = Attribute.new(attribute, selector, &callback)

  define_method :"#{attribute}" do |&block|
    if block.is_a?(Proc)
      block.call(self.class.attribute_definitions[attribute].element(node))
    else
      self.class.attribute_definitions[attribute].value(node)
    end
  end

  define_singleton_method :"find_by_#{attribute}" do |value = nil, &predicate|
    find_by_attribute(attribute, value, &predicate)
  end
end

.attribute_definitionsObject



117
118
119
# File 'lib/domino.rb', line 117

def attribute_definitions
  @attribute_definitions ||= {}
end

.attributesObject



113
114
115
# File 'lib/domino.rb', line 113

def attributes
  attribute_definitions.keys
end

.eachObject

Iterate over all the Dominos



60
61
62
63
64
# File 'lib/domino.rb', line 60

def each
  nodes.each do |node|
    yield new(node)
  end
end

.find!Object

Returns Domino for capybara node matching selector.

Raises an error if no matching node is found. For drivers that support asynchronous behavior, this method waits for a matching node to appear.



76
77
78
79
# File 'lib/domino.rb', line 76

def find!
  require_selector!
  new(Capybara.current_session.find(@selector))
end

.find_by(attributes) ⇒ Object

Returns Domino for capybara node matching all attributes.



82
83
84
# File 'lib/domino.rb', line 82

def find_by(attributes)
  where(attributes).first
end

.find_by!(attributes) ⇒ Object

Returns Domino for capybara node matching all attributes.

Raises an error if no matching node is found.



89
90
91
# File 'lib/domino.rb', line 89

def find_by!(attributes)
  find_by(attributes) || raise(Capybara::ElementNotFound)
end

.selector(s) ⇒ Object

Define the selector for this Domino

module Dom
  class Post
    selector '#posts .post'
  end
end


109
110
111
# File 'lib/domino.rb', line 109

def selector(s)
  @selector = s
end

.where(attributes) ⇒ Object

Returns collection of Dominos for capybara node matching all attributes.



94
95
96
97
98
99
100
# File 'lib/domino.rb', line 94

def where(attributes)
  select do |domino|
    attributes.all? do |key, value|
      domino.send(key) == value if domino.respond_to?(key)
    end
  end
end

Instance Method Details

#attribute(selector, &callback) ⇒ Object

Get the text of the first dom element matching a selector:

Dom::Post.all.first.attribute('.title')

Or get the value of the attribute of this dom element:

Dom::Post.all.first.attribute('&[href]')


181
182
183
# File 'lib/domino.rb', line 181

def attribute(selector, &callback)
  Attribute.new(nil, selector, &callback).value(node)
end

#attributesObject



190
191
192
193
194
# File 'lib/domino.rb', line 190

def attributes
  self.class.attributes.each_with_object({}) do |attribute, memo|
    memo[attribute] = send(attribute)
  end
end

#idObject

Dom id for this object.



186
187
188
# File 'lib/domino.rb', line 186

def id
  node['id'].nil? ? nil : %(##{node['id']})
end