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

    # 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')

Defined Under Namespace

Classes: Error

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



46
47
48
# File 'lib/domino.rb', line 46

def node
  @node
end

Class Method Details

.allObject

Get an array of all the Dominos



59
60
61
# File 'lib/domino.rb', line 59

def all
  map{|node| node}
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/)


128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# File 'lib/domino.rb', line 128

def attribute(attribute, selector = nil, &callback)
  attributes << attribute
  callbacks[attribute] = callback

  selector ||= %{.#{attribute.to_s.gsub("_", "-")}}

  class_eval %{
    def #{attribute}
      value = attribute(%{#{selector}})
      if value && self.class.callbacks[:#{attribute}].is_a?(Proc)
        self.class.callbacks[:#{attribute}].call(value)
      else
        value
      end
    end
    def self.find_by_#{attribute}(value)
      find_by_attribute(%{#{selector}}, value)
    end
  }
end

.attributesObject



105
106
107
# File 'lib/domino.rb', line 105

def attributes
  @attributes ||= []
end

.callbacksObject



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

def callbacks
  @callbacks ||= {}
end

.eachObject

Iterate over all the Dominos



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

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.



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

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

.find_by(attributes) ⇒ Object

Returns Domino for capybara node matching all attributes.



74
75
76
# File 'lib/domino.rb', line 74

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.



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

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

.selector(s) ⇒ Object

Define the selector for this Domino

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


101
102
103
# File 'lib/domino.rb', line 101

def selector(s)
  @selector = s
end

.where(attributes) ⇒ Object

Returns collection of Dominos for capybara node matching all attributes.



86
87
88
89
90
91
92
# File 'lib/domino.rb', line 86

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

Instance Method Details

#attribute(selector) ⇒ Object

Get the text of the first dom element matching a selector

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


170
171
172
173
174
# File 'lib/domino.rb', line 170

def attribute(selector)
  @node.find(selector).text
rescue Capybara::ElementNotFound
  nil
end

#attributesObject



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

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

#idObject

Dom id for this object.



177
178
179
# File 'lib/domino.rb', line 177

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